亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 漫談兼容內核之二:關于kernel-win32的對象管理.txt

?? 漫談系統內核內幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
漫談兼容內核之二:關于kernel-win32的對象管理

[align=center][size=5][b]漫談兼容內核之二:關于kernel-win32的對象管理[/b][/size][/align]
[align=center][i]毛德操[/i][/align]

    近來屢有網友提到一個旨在將Wineserver移入內核的開源項目kernel-win32;有問及其本身,希望能對其代碼作一些分析、講解的,也有問及兼容內核與此項目之間關系的。所以從這篇漫談開始就來談談kernel-win32。
    首先,兼容內核項目應當從所有(能找到的)相關開源項目吸取營養,有時候甚至就采取“拿來主義”,反正都是開源項目,只要遵守有關的規定就行。從這個意義上說,我們對于kernel-win32肯定要借鑒,也可能要“拿來”一些。但是這種借鑒和拿來的取舍必須以客觀的分析為基礎,必須與我們的終極目標相一致。相信讀者在看完從本文開始的幾篇漫談以后就會明白我為什么把Wine、ReactOS、和NDISwrapper列為兼容內核的三個主要源泉,而沒有把kernel-win32也列為主要源泉之一。

    從總體上說,kernel-win32把原來由Wine服務進程提供的某些功能和機制移入了Linux內核,具體(就目前所見版本而言)有這么一些:
    1. 文件操作。
    2. Semaphore操作。
    3. Mutex操作。
    4. Event操作。
    5. 作為同步手段的WaitForMultipleObjects()系統調用。
    所有這些機制和功能的實現都有個共同的基礎,那就是各種內核“對象(Object)”及其Handle的實現。由于已打開的對象是屬于進程的資源,又由同一進程中的所有線程所共享,所以又跟進程、線程的實現和管理有關。
    此外,kernel-win32也提供了比Wine更高效的RPC機制,用以提高應用進程與Wine服務進程通信的效率。
    但是kernel-win32的實現并不完整,甚至并不構成局部的完整性,而且已經實現的部分恰恰是相對而言難度并不高的部分,所采取的方案也還值得推敲。
    特別地,kernel-win32的目標只在于提高Wine的效率,所以并不涉及設備驅動。與兼容內核的終極目標相比,二者只是在一小段路程上有“同路”的關系。以我們的眼光看,kernel-win32無疑是朝正確的方向上在走,但是走的畢竟太近。

    Kernel-win32的代碼大體上分成三個部分。第一部分是對于Linux內核代碼的補丁,在它的kernel目錄下。第二部分是它本身的代碼,是要作為module動態安裝到內核中去的,具體的代碼文件都在它的根目錄下。第三部分是一些測試/演示程序,這是作為應用軟件在Wine上運行,或者部分地繞過Wine、與Wine并行的,特別是其中還包括一個用于啟動系統調用的庫程序win32.c,這些程序都在它的test目錄下。從邏輯上說,庫程序win32.c屬于kernel-win32,而測試/演示程序則不是;就好像Linux的內核與libc都屬于Linux,而用來測試/演示其功能的程序卻不算一樣。此外,為了幫助調試,代碼中的strace目錄下還包括了對Linux的一個調試工具strace的補丁與擴充。這個工具可以用來跟蹤應用軟件所作的Linux系統調用,實時地顯示所跟蹤的應用軟件進行具體系統調用時的參數和內核的返回值。這對于調試當然大有幫助,但在邏輯上也并不是kernel-win32的一部分。
    下面我從kernel-win32的代碼入手,對它的方方面面作一簡要的介紹和分析,本篇先說kernel-win32的對象管理,即Object和Handle的實現,實際上也必然會牽涉到進程和線程。

Object和Handle的實現
    我曾經講到,Linux把設備看成文件,所以“文件”是個廣義的概念;而Windows又進一步把文件看成“對象(Object)”,“對象”是個更廣義的概念。而標志著已打開對象的“句柄(Handle)”,則雖然在物理意義上與“打開文件號”相似(實質上都是下標),卻有著許多不同的特性,因而不能把二者混為一談。為了把Linux(內核)的文件系統機制“嫁接”到Windows的系統調用界面,必須為每個運行著Windows應用的進程(下稱“Windows進程”或“Wine進程”)準備下一個地方,用來維持一個類似于“打開文件表”的“打開對象表”。另一方面,Windows的“進程”和“線程”都與它們的Linux對應物有所不同,從而有著不同的數據結構,因此需要為每個Windows進程提供附加的數據結構,作為對Linux“進程控制塊”、即task_struct數據結構的補充,并且在二者之間建立起某種連接,例如在task_struct結構中增添一個指針等等。
    Kernel-win32本質上正是這樣做的,我們不妨看一下它對task_struct結構所打的補丁(為便于閱讀,已經作了一些整理):

[code]struct task_struct {
     . . . . . .
    - spinlock_t       alloc_lock;
    + rwlock_t        alloc_lock;
    + struct list_head   ornaments;
};[/code]

    本來alloc_lock是這個數據結構中的最后一個成分,現在把它的類型從spinlock_t改成了rwlock_t,這是因為原來的加鎖只是針對多處理器結構、防止不同處理器之間互相沖突的,現在則范圍有所擴大。而所增添的成分,則是一個雙鏈隊列頭,稱為“ornaments”。Ornament這個詞原本是“裝飾、飾物”的意思,在這里則引伸成“附件、補充”的意思。
    那么準備要鏈入這個隊列的數據結構是什么呢?這是task_ornament數據結構:

[code]struct task_ornament {
    atomic_t                           to_count;
    struct list_head                      to_list;
    const struct task_ornament_operations   *to_ops;
};[/code]
    其中的to_count顯然是個使用計數,計數為0時表示該數據結構不再有“用戶”,從而可以撤銷了。隊列頭to_list顯然就是用來將此數據結構掛入ornaments隊列的,所以這兒實質性的成分就是指針to_ops,它指向一個task_ornament_operations數據結構,里面主要是一些函數指針。目前kernel-win32只定義了一種task_ornament_operations數據結構,即wineserver_ornament_ops,后面還要講到。
    而task_ornament數據結構,則又可以是另一個數據結構WineThread中的一個成分。所以掛入ornaments隊列的(除特殊情況外) 實際上都是WineThread數據結構,此時task_ornament數據結構起著“連接件”的作用。

[code]struct WineThread {
    #ifdef WINE_THREAD_MAGIC
        unsigned           wt_magic;       /* magic number */
    #endif
    struct task_ornament  wt_ornament;    /* Linux task attachment */
    struct task_struct      *wt_task;        /* Linux task */
    Object        *wt_obj;        /* thread object */
    struct WineProcess      *wt_process;        /* Wine process record */
    struct list_head      wt_list;            /* process's thread list */
    enum WineThreadState  wt_state;        /* thread state */
    unsigned           wt_exit_status;      /* thread exit status */
    pid_t        wt_tid;             /* thread ID */
};[/code]

    當然,每個WineThread數據結構代表著一個Wine線程、即Windows線程。
    在Linux內核中,task_struct數據結構代表著一個進程或線程,是內核調度運行的對象。Wine線程既要受調度運行,就必須落實到一個task_struct數據結構、即Linux線程或進程上。反過來,作為一個受調度運行單位的task_struct數據結構(如果代表著Wine線程的話),也不能代表多個Wine線程,否則這幾個Wine線程就合并成一個調度單位了。所以這二者之間應該是一一對應的關系。既然是一一對應的關系,就應該使用指針、而不是隊列來建立互相的連系。而既然采用了隊列,隊列中又只能有一個Wine線程,那么隊列中別的成員(如果有的話),就必定是別的什么東西了。從邏輯上說,同一個隊列中的諸多成員之間有著平等的關系,可是有什么東西可以和線程處于平等的地位呢?所以這是值得推敲的,后面我還要談這個問題。
    WineThread結構中的幾個成分需要加以說明:
    指針wt_obj指向一個Object指針。在Windows中線程、進程都是“對象”,都要有一個Object數據結構作為代表。對于Object數據結構等一下再作說明。
指針wt_task指向當前進程(線程)的task_struct數據結構,這樣就可以在一個Wine線程與其所落實的Linux線程之間建立起雙向的連系(另一個方向就是順著Linux線程的ornaments隊列)。另一個指針wt_process指向一個WineProcess數據結構。顯然,WineProcess數據結構代表著Widows進程。
    在Linux內核中,進程并沒有獨立于線程的數據結構,都由task_struct作為代表。一個進程初創(通過execve()等調用與其父進程決裂)時就成為進程,同時也可以說是該進程中的第一個線程。以后,該進程通過fork()等調用創建子進程。子進程在創建之初都是與父進程共享空間的,因而都是線程,后來才通過execve()等調用另立門戶,有了自己的空間而成為進程。然而Windows不是這樣。在Windows中。一個進程與該進程的第一個線程(以及別的線程)是兩個不同的概念,有不同的數據結構。大體上說,進程代表著資源,特別是代表著一片用戶空間;而線程則代表著上下文。打個比方,進程就像是舞臺和劇本,而線程是演員及其表演的過程。在Windows內核中,這兩方面的信息分置于不同的數據結構中,而在Linux內核中則全都存放在task_struct結構中。但是Windows進程和線程的有些信息是task_struct結構中所沒有或者不同的,這也正是需要在task_struct結構之外加以“裝飾”、補充的原因。
WineProcess數據結構的定義如下:

[code]struct WineProcess {
    int                    wp_magic;      /* magic number */
    struct nls_table          *wp_nls;        /* unicode-ascii translation */
    pid_t                  wp_pid;         /* Linux task ID */
    enum WineProcessState   wp_state;        /* process state */
    struct list_head          wp_threads;      /* thread list */
    rwlock_t               wp_lock;
    struct Object            *wp_obj;         /* process object */
    struct Object            *wp_handles[0];   /* handle map */
};[/code]

    其中的隊列頭wp_threads與上面WineThread結構中的wt_list相對應,用來構成一個Windows進程與其所含的所有Windows線程之間的雙鏈隊列。如前所述,Windows進程在概念上并不落實到某個具體的Linux進程或線程,所以這個數據結構中并沒有指向task_struct結構的指針。不過實質上當然還是有連系的,因為在Linux中一個“進程”和它的“第一個線程”是一回事。這里的wp_pid既然說是Linux的“task ID”(就是Linux的pid),實際上還是一樣,還不如改成task_struct結構指針更好。
    順便提一下,Windows進程與Linux進程在優先級設置方面有很大的不同,而Linux內核是根據task_struct數據結構中記載的優先級進行調度的,這里面有個如何換算的問題。WineProcess數據結構中沒有關于進程優先級的記載,顯然kernel-win32的作者還沒有考慮這個問題。
    在Windows中進程也是“對象”,所以這里也有個Object結構指針wp_obj。這與WineThread結構中的指針wt_obj是一樣的,只不過兩個對象的類型不同,一個代表著進程,一個代表著線程。
    指針數組wp_handles[ ]才是這個數據結構的實質所在,這就是一個Windows進程的“打開對象表”。數組中的每個有效(非0)指針都指向一個Object結構;對象的類型不同,相應Object結構所代表的目標也就不同。例如有的代表著文件,有的代表著“事件”,有的代表著進程,等等。而具體指針在數組中的下標(嚴格地說是經過換算的下標,見后所述),則就是打開該對象后的Handle。在代碼中,這個數組的大小定義為0,這是因為其大小取決于為WineProcess數據結構分配的存儲空間的大小。目前,kernel-win32總是為WineProcess數據結構分配一個4KB的物理頁面,扣除這個數據結構的頭部以后就都用于這個數組,其大小的計算如下所示:

[code]#define MAXHANDLES ((PAGE_SIZE-sizeof(struct WineProcess))/sizeof(struct Object*))[/code]

    所以“打開對象表”的大小大約是1020。這與Windows相比當然差距很大(在理論上,Windows打開對象表的大小幾乎是無限的),但是實際上也夠了。
前面我一直說Handle就是下標,其實這只是就其邏輯意義而言,嚴格地說是經過換算的下標。這是因為:首先,0不是一個合法的handle數值。另一方面,Handle的數值都是4的倍數,所反映的是以字節為單位的位移。如果index是真正意義上的下標,那么handle的數值就是(index+1)* sizeof(Object*)。
總之,每個進程都有一個打開對象表,為該進程所含的諸多線程所共享,表中的每個有效指針都指向一個Object數據結構。內核中的對象就好像磁盤上的文件一樣,都有個從創建到打開、到關閉、最后被刪除的“生命周期”。每個對象都由一個Object數據結構作為代表,其定義為:

[code]/*
* object definition
* - object namespace is indexed by name and class
*/
typedef struct Object {
    struct list_head      o_objlist;       /* obj list (must be 1st) */
    #ifdef OBJECT_MAGIC
        int                o_magic;       /* magic number (debugging) */
    #endif
    atomic_t           o_count;        /* usage count */
    wait_queue_head_t  o_wait;         /* waiting process list */
    struct ObjectClass   *o_class;        /* object class */
    struct oname        o_name;        /* name of object */
    void               *o_private;      /* type-specific data */
} Object;[/code]

    對象的類型是以其數據結構中的o_class為標志的,這個指針指向哪一個ObjectClass數據結構,這個對象就是什么類型。此外,每個對象都可以有個對象名,就好像每個文件都有個文件名一樣,o_name就是用來保持對象名的數據結構。
    顯然,內核中對象的數量可以很大,這里有個如何尋找某個特定對象的問題。所以首先要按對象的類型劃分,然后為每個類別都安排若干個以對象名的hash值劃分的隊列。具體對象的Object數據結構就按其對象名的hash值鏈入所屬類別的某個隊列中,結構中的隊列頭o_objlist就是用于這個目的。
    讀者不難看出,Object數據結構中各個成分所反映的基本上都是作為某類對象的共性,而并沒有反映出具體對象的個性。所以這個結構中有個無類型的指針o_private,用來指向一個描述具體對象的數據結構。當對象的類型為線程時,這就是個WineThread數據結構;當對象的類型為文件時,這就是個WineFile數據結構;如此等等。
    如上所述,Object數據結構中的指針o_class標志著對象的類型。這是個指向某個ObjectClass結構的指針,每個ObjectClass結構代表著一種對象類型,其定義如下。

[code]struct ObjectClass {
    struct list_head    oc_next;
    const char        oc_type[6]; /* type name (5 chars + NUL) */
    int              oc_flags;
    #define OCF_DONT_NAME_ANON 0x00000001 /* don't name anonymous objects */

    int (*constructor)(Object *, void *);
    int (*reconstructor)(Object *, void *);
    void (*destructor)(Object *);
    int (*describe)(Object *, struct wineserver_read_buf *);
    int (*poll)(struct wait_table_entry *, struct WineThread *);
    void (*detach)(Object *, struct WineProcess *);

    /* lock governing access to object lists */
    rwlock_t         oc_lock;

    /* named object hash */
    struct list_head    oc_nobjs[OBJCLASSNOBJSSIZE];

    /* anonymous object list */
    struct list_head    oc_aobjs;
};[/code]

    結構中的第一個隊列頭oc_next用來構成一個對象類型、即ObjectClass數據結構的隊列。而隊列頭數組oc_nobjs[OBJCLASSNOBJSSIZE],則用來構成該對象類的hash隊列數組,具體的對象根據其對象名的hash值決定鏈入其中的哪一個隊列。數組的大小OBJCLASSNOBJSSIZE定義為16。對象也可以是無名的,無名的對象都鏈入所屬類別的無名隊列、即oc_aobjs隊列。
    ObjectClass數據結構中最具實質性的成分是一組函數指針,特別是其中的“構造”函數指針constructor,因為它決定了如何構造出一個具體類型的對象。目前keenel-win32定義了event_objclass、file_objclass、mutex_objclass、semaphore_objclass、process_objclass、thread_objclass、rpc_client_objclass、rpc_server_objclass、rpc_service_objclass、section_objclass等11種對象類型的ObjectClass數據結構。
    我們不妨以比較簡單的“信號量(semaphore)”類型為例來說明對象的創建。
    函數CreateSemaphoreA()是kernel_win32對同名系統調用在內核中的實現,其目的是為當前進程創建并打開一個(內核中的)帶有對象名的信號量。我們先跳過系統調用如何進入內核這一步,從這個函數開始看有關的代碼。

[code]int CreateSemaphoreA(struct WineThread *filp, struct WiocCreateSemaphoreA *args)
{
    HANDLE hSemaphore;
    Object *obj;

    obj = CreateObject(filp,&semaphore_objclass,args->lpName,args, &hSemaphore);
    . . . . . .
    return (int) hSemaphore;
} /* end CreateSemaphoreA() */[/code]

    調用參數filp指向當前線程的WineThread數據結構,這是由kernel_win32所實現的系統調用機制所提供的。另一個參數args,則是指向一個WiocCreateSemaphoreA數據結構的指針。Kernel_win32所實現的系統調用機制把Windows系統調用的參數都組裝在一個數據結構中,再把這個結構的起始地址作為參數傳給內核。為此,Kernel_win32為其所實現的每個Windows系統調用都定義了一個數據結構,WiocCreateSemaphoreA就是為系統調用CreateSemaphoreA()的參數而定義的數據結構。
    CreateSemaphoreA()的主體就是對函數CreateObject()的調用。由于要創建的對象是信號量,就把此種對象類型的數據結構semaphore_objclass的起始地址也作為參數傳了下去。參數&hSemaphore則是用來返回Handle的。

[code][CreateSemaphoreA() > CreateObject()]

Object *CreateObject(struct WineThread *thread, struct ObjectClass *clss,const char *name, void *data, HANDLE *hObject)
{
    struct WineProcess *process;
    struct oname oname;
    Object *obj, **ppobj, **epobj;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日日夜夜免费精品| 欧美色网一区二区| 欧洲精品在线观看| 国产视频视频一区| 午夜日韩在线观看| aaa欧美日韩| 精品国一区二区三区| 一区二区三区欧美久久| 成人性生交大片免费看视频在线 | 最近中文字幕一区二区三区| 日韩二区在线观看| 色婷婷精品大视频在线蜜桃视频| 欧美成人三级在线| 丝袜美腿亚洲一区| 色婷婷综合视频在线观看| 国产校园另类小说区| 美国毛片一区二区三区| 日本道精品一区二区三区| 日本一区二区三区高清不卡| 久久精品国产精品亚洲综合| 欧美日韩视频第一区| 国产精品萝li| 国产不卡高清在线观看视频| 欧美大片日本大片免费观看| 性做久久久久久| 欧美性色黄大片手机版| 亚洲欧美影音先锋| 成人av网址在线| 中文字幕av不卡| 国产成人精品在线看| 久久女同精品一区二区| 国模娜娜一区二区三区| 精品国产人成亚洲区| 美女一区二区久久| 精品国产乱码久久久久久牛牛 | 欧美一区二区三区视频免费播放| 亚洲一区二区视频| 欧美日韩一区二区在线视频| 亚洲国产精品影院| 欧美日韩精品福利| 天天色天天操综合| 日韩一区国产二区欧美三区| 狠狠久久亚洲欧美| 久久久亚洲高清| 成人黄色免费短视频| 亚洲欧洲日韩综合一区二区| 91美女精品福利| 亚洲444eee在线观看| 日韩精品一区二区三区在线播放 | 久久99精品久久久久| 精品久久久影院| 成人丝袜高跟foot| 一区二区三区欧美激情| 91精品国产日韩91久久久久久| 精品一区中文字幕| 国产精品天天看| 欧美色图在线观看| 日产欧产美韩系列久久99| 欧美精品一区二区三区久久久| 国产 日韩 欧美大片| 一区二区三区欧美激情| 精品国产一区二区精华 | 国内精品视频666| 国产农村妇女毛片精品久久麻豆 | 免费在线观看日韩欧美| 中文字幕精品一区| 欧美日韩国产一二三| 国产一区二区三区高清播放| 中文字幕日本不卡| 欧美一级日韩免费不卡| 成人的网站免费观看| 日韩精品1区2区3区| 国产精品乱人伦中文| 欧美午夜理伦三级在线观看| 精品一区二区三区视频在线观看| 国产午夜久久久久| 555夜色666亚洲国产免| 国产乱码精品一区二区三| 亚洲视频在线一区| www精品美女久久久tv| 在线一区二区三区四区| 国产剧情在线观看一区二区| 亚洲愉拍自拍另类高清精品| 久久久久9999亚洲精品| 91麻豆精品国产91久久久久| 不卡的电视剧免费网站有什么| 亚洲成人先锋电影| 亚洲色图清纯唯美| 久久综合中文字幕| 91极品视觉盛宴| 国产电影一区在线| 久久精工是国产品牌吗| 一区二区三区中文在线观看| 国产日韩欧美制服另类| 制服丝袜成人动漫| 欧美午夜一区二区| 91丨九色丨蝌蚪富婆spa| 国产精品性做久久久久久| 另类人妖一区二区av| 天天综合色天天综合| 一区二区三区精品视频| 久久精品夜色噜噜亚洲aⅴ| 精品久久国产97色综合| 91精品国产手机| 337p亚洲精品色噜噜狠狠| 91网站在线播放| 不卡的av在线播放| 成人av网址在线| 国产一区二区三区不卡在线观看| 亚洲不卡在线观看| 亚洲www啪成人一区二区麻豆| 亚洲欧美欧美一区二区三区| 中文字幕免费不卡| 国产亚洲精品资源在线26u| 久久综合色播五月| 国产人成亚洲第一网站在线播放| 2021久久国产精品不只是精品 | 欧美另类一区二区三区| 欧美系列在线观看| 欧美日韩综合不卡| 欧美日韩国产综合视频在线观看| 欧美自拍偷拍午夜视频| 欧美视频在线观看一区| 欧美色图在线观看| 日韩一区二区不卡| 精品国产91洋老外米糕| 久久久www成人免费无遮挡大片| 欧美精品一区二区在线播放| 国产亚洲一本大道中文在线| 中文字幕免费一区| 亚洲精品伦理在线| 午夜精品在线看| 琪琪久久久久日韩精品| 国产精品一品视频| 国产成人精品一区二区三区四区| 福利一区二区在线| 91美女片黄在线观看| 制服视频三区第一页精品| 欧美成人激情免费网| 亚洲欧美综合在线精品| 亚洲国产精品一区二区久久恐怖片| 香蕉成人啪国产精品视频综合网| 日本最新不卡在线| 大白屁股一区二区视频| 色综合久久久久综合体| 日韩一级视频免费观看在线| 中文字幕av一区二区三区免费看 | 极品少妇xxxx精品少妇| 成人国产精品免费观看| 欧美午夜寂寞影院| 欧美成人一级视频| 一区二区三区**美女毛片| 久久国产精品99久久人人澡| 99综合电影在线视频| 欧美一区二区视频网站| 中文字幕一区二区在线观看| 日本vs亚洲vs韩国一区三区| 成人性生交大片免费看中文网站| 欧美老女人在线| 国产日韩成人精品| 午夜亚洲国产au精品一区二区| 国产综合成人久久大片91| 欧美视频在线一区| 国产精品麻豆视频| 理论片日本一区| 欧美日韩一区视频| 国产精品国产三级国产aⅴ原创| 日韩电影在线一区| 91福利视频网站| 中文字幕乱码亚洲精品一区| 麻豆精品在线看| 欧美三级韩国三级日本一级| 中文字幕在线观看一区二区| 精品在线免费视频| 欧美精品亚洲二区| 一区二区三区久久久| eeuss鲁片一区二区三区在线看| 精品少妇一区二区三区免费观看| 午夜一区二区三区视频| 91麻豆swag| 最新久久zyz资源站| 成人国产在线观看| 久久久精品免费免费| 精品一区二区久久| 日韩三级在线免费观看| 日韩精品欧美精品| 欧美日韩国产精品自在自线| 亚洲精品日产精品乱码不卡| 不卡视频在线看| 国产精品理论在线观看| 国产九色精品成人porny| 久久色在线观看| 国产麻豆欧美日韩一区| 久久久久久久久久久久久久久99| 免费在线观看不卡| 欧美精品一区二区三区四区| 麻豆91精品视频| 精品久久99ma| 国产91丝袜在线播放| 中文字幕成人网|