國產(chǎn)操作系統(tǒng)最致命的短板,被這個(gè)開源軟件補(bǔ)上了!
“國產(chǎn)操作系統(tǒng)為什么沒人用?”
“因?yàn)樯厦鏇]有軟件。”
“那么多軟件,下載下來,一安裝不就行了嗎?”
“不行,現(xiàn)在的軟件都是給Windows開發(fā)的,國產(chǎn)操作系統(tǒng)是基于Linux爆改的,軟件跑不了?!?/p>
“那就給國產(chǎn)Linux開發(fā)軟件???!”
“沒人開發(fā),因?yàn)閲a(chǎn)操作系統(tǒng)沒人用?!?/p>
“你這不就成了雞生蛋,蛋生雞的了,無解循環(huán)......”
這是我和一個(gè)朋友關(guān)于國產(chǎn)桌面操作系統(tǒng)的一次對話。
其實(shí)這幾年國產(chǎn)桌面操作發(fā)展得相當(dāng)不錯(cuò),像Deepin,統(tǒng)信等根據(jù)國人的審美和操作習(xí)慣,做了很多本土化工作,并且內(nèi)置了各種常用的軟件如WPS Office、搜狗輸入法、有道詞典、網(wǎng)易云音樂等,用來做日常辦公完全夠用。
圖片
但是,國產(chǎn)操作系統(tǒng)做得再好,也只能涵蓋一部分軟件,對于Windows龐大生態(tài)生態(tài)中那千千萬萬的軟件,只能望洋興嘆了。
如果你要用的軟件不被國產(chǎn)操作系統(tǒng)支持,那怎么辦?
最簡單的方案是用類似VirtualBox這樣的虛擬機(jī),在虛擬機(jī)中運(yùn)行Windows,然后在Windows上安裝想要的軟件。
圖片
這種一層摞一層的辦法有用,就是效率太低,運(yùn)行速度太慢:
圖片
有沒有辦法,既能在Linux上運(yùn)行Windows軟件,又能避免效率的損失呢?
有!這個(gè)軟件叫做Wine。
圖片
Wine不是虛擬機(jī),而是一個(gè)軟件兼容層,它通過“轉(zhuǎn)發(fā)”的方式,讓W(xué)indows程序可以運(yùn)行在Linux之上。
要想理解Wine的秘密,必須得從最底層看起。
1.可移植的CPU指令
比如這段代碼:
int foo(int x) {
return x * x;
}
都基于x86 CPU編譯(這一點(diǎn)兒很重要),在Linux上這樣的:
圖片
在Windows上是這樣的:
圖片
看起來差別相當(dāng)大,對吧?
但是,由于兩者生成的代碼都是基于x86 CPU的,換句話說,CPU指令集(mov、imul、ret之類)是完全相同的。
圖片
Linux上可執(zhí)行文件是ELF格式,下圖的.text 區(qū)域就是CPU的指令
圖片
Window上的可執(zhí)行文件是PE格式,CPU指令也在.text區(qū)域。
圖片
既然.text區(qū)域的CPU指令在Windows和Linux之間是“可移植的”,你可能立刻會(huì)想到,如果有一個(gè)程序,可以把foo函數(shù)在Windows編譯出的.text 給“取”出來,拿到Linux上執(zhí)行,應(yīng)該是可以運(yùn)行的。
Wine其實(shí)就是這么干的,它把Windows可執(zhí)行文件加載到內(nèi)存中,分析一下,找到可執(zhí)行代碼的位置,跳轉(zhuǎn)到這個(gè)地方執(zhí)行就可以了!
2.系統(tǒng)調(diào)用
如果事情就這么簡單,任何人都可以寫一個(gè)Wine,Windows上的海量軟件就可以輕松移植到Linux上,Windows生態(tài)的優(yōu)勢將不復(fù)存在。
但Windows的桌面霸主地位堅(jiān)如磐石,這其中的關(guān)鍵就是:系統(tǒng)調(diào)用。
操作系統(tǒng)是對硬件功能的封裝,它對外提供了一系列服務(wù)如讀寫硬盤、讀寫內(nèi)存、進(jìn)程管理等。
應(yīng)用程序想使用這些服務(wù),必須通過系統(tǒng)調(diào)用來進(jìn)行,別無它法。
而Windows和Linux的系統(tǒng)調(diào)用,是完全不同的。
名稱不同、參數(shù)不同、語義也不同。
圖片
一個(gè)稍微有用的應(yīng)用程序,肯定要使用系統(tǒng)調(diào)用(無論是直接還是間接方式),那就立刻和操作系統(tǒng)綁定了。
比如這個(gè)hello world。
#include <stdio.h>
int main() {
printf("Hello!\n");
return 0;
}
在Linux上是這樣的,它調(diào)用的是puts函數(shù)。
圖片
在Windows上編譯后是這樣的,調(diào)用的是printf函數(shù)。
圖片
puts和printf都C標(biāo)準(zhǔn)庫的函數(shù),C標(biāo)準(zhǔn)庫最終還是走到系統(tǒng)調(diào)用那里,畢竟你要在控制臺(tái)輸出“Hello!”,這事兒只能操作系統(tǒng)來辦。
要想在Linux上運(yùn)行Windows程序,有兩條路。
(1)把Windows系統(tǒng)調(diào)用在Linux上重新實(shí)現(xiàn)一遍,這和重寫OS差不多了。
(2)把Windows系統(tǒng)調(diào)用攔截,轉(zhuǎn)發(fā)到Linux的系統(tǒng)調(diào)用。
Wine開發(fā)團(tuán)隊(duì)選擇了第二條道路,當(dāng)應(yīng)用程序調(diào)用Windows 系統(tǒng)調(diào)用時(shí),Wine進(jìn)行“攔截”,然后轉(zhuǎn)發(fā)到Linux的系統(tǒng)調(diào)用。
圖片
這個(gè)事情畫個(gè)圖很簡單,實(shí)現(xiàn)起來太麻煩了。
Windows的系統(tǒng)調(diào)用非常多,源碼又不公開,全是黑匣子,我們不知道Windows內(nèi)部到底是如何實(shí)現(xiàn)的,Windows文檔又很差......(大膽猜測一些,微軟是故意的)。
更要命的是,這些系統(tǒng)調(diào)用還存在一些錯(cuò)誤、缺陷、奇怪的副作用,Wine在攔截轉(zhuǎn)發(fā)的時(shí)候,這些錯(cuò)誤和缺陷不但不能修復(fù),還必須原封不動(dòng)地去復(fù)現(xiàn)它們。
如果不這么干,那些Windows軟件在Linux上運(yùn)行起來的行為就不同了。
這還不算完,別忘了Windows游戲啊,它們都在調(diào)用微軟的DirectX,這是微軟專門為游戲開發(fā)提供的API,僅支持Windows。
在Linux平臺(tái)下也有個(gè)對應(yīng)的東西,原來叫OpenGL,現(xiàn)在新一代的圖形API叫做Vulkan。
很明顯,DirectX和Vulkan是不同的東西。
圖片
為了把DirectX調(diào)用轉(zhuǎn)換成Vulkan,Valve(Steam就是他們家的)和CodeWeavers(主要贊助Wine)合作開發(fā)了Proton。
圖片
Proton 最初于 2018 年 8 月 21 日發(fā)布,當(dāng)時(shí)Valve還發(fā)布了一個(gè) 27 款游戲的名單,這些游戲經(jīng)過測試和認(rèn)證,性能與 Windows 原生版本相同,無需最終用戶進(jìn)行調(diào)整。其中包括《毀滅戰(zhàn)士》(2016 年)、《雷神之錘》和《最終幻想 VI》等。
3.總結(jié)
看了Wine干的這些事情,你肯定會(huì)感慨,讓W(xué)indows應(yīng)用在Linux上順利地跑起來可真不容易啊。
這是沒辦法的事情,誰讓W(xué)indows是桌面操作系統(tǒng)的老大呢?
微軟通過Windows系統(tǒng)調(diào)用API和DirectX等API,構(gòu)建了非常寬的護(hù)城河。
開源的Wine在這個(gè)護(hù)城河上建立一座橋,這座橋雖然還不完美,但足以讓大量的Windows應(yīng)用來到Linux的世界快樂地玩耍。
相信國產(chǎn)操作系統(tǒng)一定會(huì)充分地利用Wine這樣開源界的成果,讓自己的生態(tài)變得更加豐富。