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