<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > Linux可加載內(nèi)核模塊機制的研究與應(yīng)用

          Linux可加載內(nèi)核模塊機制的研究與應(yīng)用

          作者: 時間:2012-03-31 來源:網(wǎng)絡(luò) 收藏

          關(guān)于模塊加載,可以用圖3.1來簡要描述:

          圖3.1 模塊的裝入

          insmod程序必須找到要求加載的內(nèi)核模塊,這些內(nèi)核模塊是已鏈接的目標文件,與其他文件不同的是,它們被鏈接成可重定位映象即映象沒有被鏈接到特定地址上。insmod將執(zhí)行一個特權(quán)級系統(tǒng)調(diào)用來查找內(nèi)核的輸出符號,這些符號都以符號名和數(shù)值形式如地址值成對保存。內(nèi)核輸出符號表被保存在內(nèi)核維護的模塊鏈表的第一個module結(jié)構(gòu)中。只有特殊符號才被添加,它們在內(nèi)核編譯與鏈接時確定。insmod將模塊讀入虛擬內(nèi)存并通過使用內(nèi)核輸出符號來修改其未解析的內(nèi)核函數(shù)和資源的引用地址。這些工作采取由insmod程序直接將符號的地址寫入模塊中相應(yīng)地址來進行。

          當(dāng)insmod修改完模塊對內(nèi)核輸出符號的引用后,它將再次使用特權(quán)級系統(tǒng)調(diào)用申請足夠的空間容納新模塊。內(nèi)核將為其分配一個新的module結(jié)構(gòu)以及足夠的內(nèi)核內(nèi)存來保存新模塊,并將其插入到內(nèi)核模塊鏈表的尾部,最后將新模塊標志為UNINITIALIZED。insmod將模塊拷貝到已分配空間中,如果為它分配的內(nèi)核內(nèi)存已用完,將再次申請,但模塊被多次加載必然處于不同的地址。另外此重定位工作包括使用適當(dāng)?shù)刂穪硇薷哪K映象[5]。如果新模塊也希望將其符號輸出到系統(tǒng)中,insmod將為其構(gòu)造輸出符號映象表。每個內(nèi)核模塊必須包含模塊初始化和結(jié)束函數(shù),所以為了避免沖突它們的符號被設(shè)計成不輸出,但是insmod必須知道這些地址,這樣可以將它們傳遞給內(nèi)核。在所有這些工作完成以后,insmod將調(diào)用初始化代碼并執(zhí)行一個特權(quán)級系統(tǒng)調(diào)用將模塊的初始化和結(jié)束函數(shù)地址傳遞給內(nèi)核。當(dāng)將一個新模塊加載到內(nèi)核中時,內(nèi)核必須更新其符號表并修改那些被新模塊使用的老模塊[6]。那些依賴于其他模塊的模塊必須在其符號表尾部維護一個引用鏈表并在其module數(shù)據(jù)結(jié)構(gòu)中指向它。內(nèi)核調(diào)用模塊的初始化函數(shù),如果成功將安裝此模塊。模塊的結(jié)束函數(shù)地址被存儲在其module結(jié)構(gòu)中,將在模塊卸載時由內(nèi)核調(diào)用,模塊的狀態(tài)最后被設(shè)置成RUNNING。

          3.2 模塊的卸載

          模塊可以使用rmmod命令刪除,但是請求加載模塊在其使用計數(shù)為0時,自動被系統(tǒng)刪除。kmod在其每次idle定時器到期時都執(zhí)行一個系統(tǒng)調(diào)用,將系統(tǒng)中所有不再使用的請求加載模塊刪除。

          關(guān)于模塊卸載,可以用圖3.2來描述:

          內(nèi)核中其他部分還在使用的模塊不能被卸載。例如系統(tǒng)中安裝了多個VFAT文件系統(tǒng)則不能卸載VFAT模塊。執(zhí)行l(wèi)smod將看到每個模塊的引用計數(shù)。模塊的引用計數(shù)被保存在其映象的第一個常字中,這個字還包含autoclean和visited標志。如果模塊被標記成autoclean,則內(nèi)核知道此模塊可以自動卸載。visited標志表示此模塊正被一個或多個文件系統(tǒng)部分使用,只要有其他部分使用此模塊則這個標志被置位。每次系統(tǒng)要將沒有被使用的請求加載模塊刪除時,內(nèi)核將在所有模塊中掃描,但是一般只查看那些被標志為autoclean并處于running狀態(tài)的模塊。如果某模塊的 visited標記被清除則它將被刪除。其他依賴于它的模塊將修改各自的引用域,表示它們間的依賴關(guān)系不復(fù)存在。此模塊占有的內(nèi)核內(nèi)存將被回收。

          4. 的應(yīng)用

          基本思想是:數(shù)據(jù)分組從網(wǎng)絡(luò)設(shè)備到用戶程序空間傳遞的過程中,減少數(shù)據(jù)拷貝次數(shù),減少系統(tǒng)調(diào)用,實現(xiàn)CPU的零參與,徹底消除CPU在這方面的負載。的實現(xiàn)分為實現(xiàn)DMA數(shù)據(jù)傳輸和地址映射兩個部分。其中DMA數(shù)據(jù)傳輸與本文關(guān)系不大,就不詳細敘述了,這里主要介紹應(yīng)用機制實現(xiàn)的地址映射。

          地址映射的基本原理是在內(nèi)核空間申請內(nèi)存,通過proc文件系統(tǒng)和mmap函數(shù)將其映射到用戶空間來允許應(yīng)用程序訪問,這樣就消除了內(nèi)核空間到應(yīng)用程序空間的數(shù)據(jù)拷貝。地址映射部分的實現(xiàn)主要分為以下三步:

          第一,建立LKM的基本結(jié)構(gòu),包括編寫初始化和結(jié)束函數(shù)等。

          第二,聲明完成映射功能所需要的函數(shù),主要有分配和初始化內(nèi)核內(nèi)存函數(shù)init_mem(),釋放內(nèi)核內(nèi)存函數(shù)del_mem(),向內(nèi)核內(nèi)存輸入內(nèi)容的函數(shù)put_mem()等。

          第三,在初始化函數(shù)中應(yīng)用第二步建立的函數(shù)分配一塊內(nèi)存空間、輸入內(nèi)容、建立proc文件系統(tǒng)入口。在結(jié)束函數(shù)中釋放已分配的內(nèi)核內(nèi)存,刪除proc文件系統(tǒng)入口。

          編寫應(yīng)用程序測試該LKM,發(fā)現(xiàn)已經(jīng)達到了映射內(nèi)核內(nèi)存到應(yīng)用程序空間的目的。在實現(xiàn)的過程中采用LKM機制不但便于調(diào)試而且大大減少了開發(fā)時間。

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


          關(guān)鍵詞: LKM Linux 零拷貝

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();