1. 程式人生 > >[轉]Wine的一些相關原理

[轉]Wine的一些相關原理

    作者:李笑天
    關於把wineserver整合進linux的核心,曾經在在wine的官方有過這麼一個專案,不過到2000年就沒有人維護了,現在在wine的cvs裡面還能看到,程式碼是針對kernel2.4的。它基本上實現了當時wineserver的功能,不過現在肯定用不了。

      我想談談對wine的理解。wine分為wine客戶端程式和wineserver。關於wineserver為什麼要存在,主要是因為windows 的核心物件,跟linux(和其他的作業系統)的核心物件的不同,比如程序,執行緒,檔案,訊號...等等,實質上就是定義的資料結構,型別不一樣,所以 windows程式執行的時候,需要啟動一個虛擬的win32子系統,wineserver來管理這些物件以及一些公有的環境變數,如登錄檔。同時, wineserver還負責對訊息和事件(主要是Xwindows事件)的同步。因此wineserver的效率以及windows程式跟 wineserver的通訊機制是提高wine效率的關鍵。

      windows程式由wine-preloader載入(載入所需的dll和共享庫,完成程式碼的重定位)以後,首先檢查wineserver是否執行,沒有執行就啟動它。利用socket建立連線。最新版的程式碼在wine/dlls/ntdll/server.c裡面。wineserver執行以後,首先建立一個socket套接字,等待客戶端連線,從客戶端連線開始,呼叫create_process建立一個虛擬的windows程序,作為整個 wine的主程序,(相當於linux的init程序)。然後它建立一個pipe(管道),作為客戶端和wineserver通訊的工具。然後 wineserver進入main_loop()函式,main_loop主要輪訓各個poll佇列,讀取客戶端的請求,並執行相應的服務。 wineserver還具有"程序排程”的功能。因此wine的設計很具有科學性 的。

    不過,由於wineserver和wineclient之間採用pipe通訊,並且採用輪詢的方式查詢,所以效率不是很高,windows程式執行起來比較慢。因為wineserver本身是一個使用者太的程序,優先順序比較低,其他的因素加起來就更慢了。wineX曾經試圖利用共享記憶體實現 wineserver跟wineclient之間的通訊,事實上,效果還是比較理想,提高速度四倍。

       所以,理論上說,把wineserver從使用者態移植到核心裡面,會顯著的提高效率,而且很多使用者態不能完成的事情,在核心裡面都可以完成,比如,跨程序呼叫,跨程序讀寫,遠端執行緒,全域性記憶體分配等等。雖然這些在使用者態用某些方式也能完成(比如使用ptrace函式)不過速度很慢很慢。移植到核心還可以至少節省一半的排程時間。

       不過,說起來輕鬆,做起來比較麻煩,到底怎麼移植,以何種方式移植是比較困難的事情。當然最直接的方式就是實現成系統呼叫,這樣比較快,也容易理解。不過這樣會改變現有的linux kernel 的結構,也會改變wine的結構,工作量很大。還有一種方式就是實現一個裝置驅動,實現wineserer的功能,使用ioctl進行呼叫,這樣工作量相對小一點,而且不用修改核心。還有一種有趣的方式是用netlink,linux支援netlink socket,使用它核心跟使用者程序之間可以使用標準的socket函式進行通訊,這樣跟現有的wineserver結構很類似,工作量更小一點。我已經做過嘗試,不過移植的時候還有一大堆的問題,主要還是對linux核心的一些特性不太瞭解,比如在核心態直接讀取檔案系統。不過我覺得用這種方式實現應該沒什麼太大的問題。如果各位有更好的方法,可以討論討論。