linux内核引入模块机制好处,linux内核模块的版本检查机制
linux內核對插入的內核模塊進行嚴格的版本檢查,即使一個小版本號不一致也會導致加載的不成功,這完全是為了內核本身運行安全。由于linux內核的發布是基于版本號的,而所有的內核模塊的開發必須依賴內核頭文件--其使用的內核導出符號均在頭文件中,該頭文件肯定屬于一個特定版本的源碼樹,因此模塊也就間接依賴了該版本的源碼樹。那么到底為何內核對模塊的版本檢查如此嚴格呢?因為每當一個新的版本發布,可能導致接口的改變,如果不嚴格檢查版本則可能導致內核crash,然而如果舊版本的模塊難道沒有任何辦法載入到新版本的內核中嗎?不是的!只要它使用的接口在兩個版本間沒有改變即可,這是通過一個非常有意思的機制實現的,這就是單獨接口符號的crc校驗機制。其實windows的ddk編譯的驅動要想載入內核而不發生意外,接口的一致性也是必要的,只是ddk的編譯環境為開發者屏蔽了很多版本方面的信息,第一,ddk自帶了頭文件并且windows的內核無法單獨進行下載,它是和操作系統一起被發行的;第二,操作系統的內核,庫,ddk是由微軟統一管理的。因此,我們會覺得ddk編譯出的驅動對系統版本沒有要求,其實這是不對的,在ddk的Build Environments中,不是也有版本之分別嗎?只是它的版本沒有linux那么多罷了!
首先要知道,內核中只要是EXPORT的符號,都會有一個crc校驗碼,這些校驗碼保存在內核映像中,這些校驗碼用于和載入內核的模塊中包含的crc校驗碼作比較。模塊編譯的過程中,genksyms這個程序起了很大的作用,其實編譯模塊最終的結果--一個ko文件并不僅僅是你的模塊源代碼c文件經過編譯器和鏈接器處理過后的結果,而是被genksyms插入了一些額外的數據,就是這些數據作為版本控制的依據起了很大的作用。簡單來說就是genksyms分析模塊源代碼文件(編譯預處理后的),將其中使用的函數,變量等抽出來,然后再為這些函數,變量中的每一個生成一個crc校驗碼,生成校驗碼輸入就是函數的名稱,參數類型以及變量的名稱,類型等,然后這些crc校驗和被寫入一個.mod.c文件中,最終編譯器和鏈接器將這個.mod.c文件和源代碼文件一起編譯和鏈接,最終生成的ko中就包含了這些由genksyms生成的crc校驗和。
當模塊加載的時候,內核會逐一的抽出ko模塊中的每一個符號以及其對應的crc校驗碼,然后和內核本身保存的該符號的crc校驗碼做比較,只要有一個符號的crc校驗碼不同就說明該模塊的版本不正確,因為如果該模塊確實是在當前內核版本下編譯的,那么其符號的crc校驗碼將會和內核本身相應符號的crc校驗碼一致,畢竟它們的算法一樣,輸入信息也一樣。
以上的這種機制可以被用作一種動態的版本控制,比如動態鏈接庫的版本控制,這樣可以減輕庫混亂帶來的危害,我們需要作的僅僅是為每一個動態庫生成一個類似.mod.c的文件,姑且稱為.version.c,這個文件中包含所有引用接口的crc校驗碼以及引用接口本身,然后修改動態庫的加載機制,增加版本檢查相關的邏輯,也就是一個crc比對的邏輯。
總結
以上是生活随笔為你收集整理的linux内核引入模块机制好处,linux内核模块的版本检查机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux+用户的shell,linux
- 下一篇: linux上用的端口转发工具,Linux