Linux2.6與2.4內核驅動程序的區別

火星人 @ 2014-03-26 , reply:0



  為了徹底防止對正在被使用的內核模塊進行錯誤操作,linux2.6內核在載入和導出內核模塊方面都較2.4內核有所改進,避免了用戶執行將導致系統崩潰的操作(例如強制刪除模塊等)。同時,當驅動程序需要在多個文件中包含頭文件時,不必定義宏來檢查內核的版本。與2.4內核相比,2.6內核在可擴展性、吞吐率等方面有較大提升,其新特性主要包括:使用了新的調度器演算法;內核搶佔功能顯著地降低了用戶互動式應用程序;多媒體應用程序等類似應用程序的延遲;改進了線程模型以及對NPTL的支持,顯著改善了虛擬內存在一定成程度負載下的性能;能夠支持更多的文件系統;引進了內存池技術;支持更多的系統設備,在2.4內核中有約束大型系統的限制,其支持的每一類設備的最大數量為256,而2.6內核則徹底打破了這些限制,可以支持4095種主要的設備類型,且每個單獨的類型又可以支持超過一百萬個的子設備;支持反向映射機制(reverse mapping),內存管理器為每一個物理頁建立一個鏈表,包含指向當前映射頁中每個進程的頁表條目的指針。該鏈表叫PTE鏈,它極大的提高了找到那些映射某個頁的進程的速度。

  Linux操作系統的設備驅動程序是在內核空間運行的程序,其中涉及很多內核的操作,隨著Linux內核版本的升級,驅動程序的開發必然也要作出相應的修改,總之,在linux2.6內核上編寫設備驅動程序時具體要注意以下幾個方面:

  1)Linux2.6內核驅動程序必須由MODULE_LICENSE("Dual BSD/GPL")語句來定義許可證,而不能再用2.4內核的MODULE_LICENSE("GPL")。否則,在編譯時會出現警告提示。

  2)Linux2.6內核驅動程序可以用int try_module_get(&module)來載入模塊,用module_put()函數來卸載模塊,而以前2.4內核使用的宏MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT則可不用。

  3)前面給出的字元型設備驅動程序模型中結構體file_operations的定義要採用下面的形式。這是因為在Linux內核中對結構體的定義形式發生了變化,不再支持原來的定義形式。

  4)就字元型設備而言,test_open()函數中向內核註冊設備的調用函數register_chrdev()可以升級為int register_chrdev_region(dev_t from,unsigned count,char * name),如果要動態申請主設備號可調用函數int alloc_chrdev_region(dev_t * dev,unsigned baseminor,unsigned count,char * name)來完成;原來的註冊函數還可以用,只是不能註冊設備號大於256的設備,同理,對於塊設備和網路設備的註冊函數也有著相對應的代替函數。

  5)在聲明驅動程序是否要導出符號表方面有著很大的變化。當驅動程序模塊裝入內核后,它所導出的任何符號都會變成公共符合表的一部分,在/proc/ksyms中可以看到這些新增加的符號。通常情況之下,模塊只需實現自己的功能,不必導出任何符號,然而,如果有其他模塊需要使用模塊導出的符號時,就必須導出符號,只有顯示的導出符號才能被其他模塊使用,Linux2.6內核中默認不導出所有的符號,不必使用EXPORT_NO_SYMBOLS宏來定義;而在2.4內核中恰恰相反,它默認導出所有的符號,除非使用EXPORT_NO_SYMBOLS,因此在上面給出的範例中可以省略去該定義語句。

  6)Linx內核統一了很多設備類型,同時也支持更大的系統和更多的設備,原來Linux2.4內核中的變數kdev_t已經被廢除不可用,取而代之的是dev_t。它拓展到了32位,其中包括12位主設備號和20位次設備號。調用函數為unsigned int iminor(struct inode * inode)和unsigned int imajor(struct inode * inode),而不再用Linux2.4版本中的int MAJOR(kdev_t dev)和int MINOR(kdev_t dev)。

  7)所有的內存分配函數不再包含在頭文件中,而是包含在中,而原來的已經不存在。所以當在驅動程序中要用到函數kmalloc()或kfree()等內存分配函數時,就必須要定義頭文件而不是。同時,前面提到的申請內存和釋放內存函數的具體參數也有了一定的改變,包括:分配標誌GFP_BUFFER被取消,取而代之的是GFP_NOIO和GFP_NOFS;新增了_GFP_REPEAT、_GFP_NOFAIL和_GFP_NORETRY分配標誌等,使得內存操作更加方便。

  8)因為內核中有些地方的內存分配是不允許失敗的,所以為了確保這種情況下得成功分配,linux2.6版本內核中開發了一種稱為"內存池"的抽象。內存池其實相當於後備的高速緩存,以便在緊急狀態下使用。要使用內存池的處理函數時,必須包含頭文件。內存池處理函數主要有以下幾個:mempool_t *mempool_create()、void*mempool_alloc()、void mempool_free()、int mempool_resize();

  另外值得一提的是:2.6內核為了區別以.o為擴展名的常規對象文件,將內核模塊的擴展名改為.ko,所以驅動程序最後是被編譯為ko後綴的可載入模塊,在應用程序中載入驅動程序模塊時要注意。



[火星人 via ] Linux2.6與2.4內核驅動程序的區別已經有140次圍觀

http://www.coctec.com/docs/linux/show-post-186318.html