linux 編譯模塊


第一步, 我們需要看一下模塊如何必須被建立. 模塊的建立過程與用戶空間的應用程序的 建立過程有顯著不同; 內核是一個大的, 獨立的程序, 對於它的各個部分如何組合在一起 有詳細的明確的要求. 建立過程也與以前版本的內核的過程不同; 新的建立系統用起來更 簡單並且產生更正確的結果, 但是它看起來與以前非常不同. 內核建立系統是一頭負責的 野獸, 我們就看它一小部分. 在內核源碼的 Document/kbuild 目錄下發現的文件, 任何想 理解表面之下的真實情況的人都要閱讀一下.

 

 

16

 

有幾個前提, 你必須在能建立內核模塊前解決. 第一個是保證你有版本足夠新的編譯器, 模塊工具, 以及其他必要工具. 在內核文檔目錄下的文件 Documentation/Changes 一直列 出了需要的工具版本; 你應當在向前走之前參考一下它. 試圖建立一個內核(包括它的模 塊), 用錯誤的工具版本, 可能導致不盡的奇怪的難題. 注意, 偶爾地, 編譯器的版本太新 可能會引起和太老的版本引起的一樣的問題. 內核源碼對於編譯器做了很大的假設, 新的 發行版本有時會一時地破壞東西.

 

如果你仍然沒有一個內核樹在手邊, 或者還沒有配置和建立內核, 現在是時間去做了. 沒 有源碼樹在你的文件系統上, 你無法為 2.6 內核建立可加載的模塊. 實際運行為其而建立 的內核也是有幫助的( 盡管不是必要的 ).

 

一旦你已建立起所有東西, 給你的模塊創建一個 makefile 就是直截了當的. 實際上, 對 於本章前面展示的" hello world" 例子, 單行就夠了:

 

obj-m := hello.o

 

熟悉 make , 但是對 2.6 內核建立系統不熟悉的讀者, 可能奇怪這個 makefile 如何工作. 畢竟上面的這一行不是一個傳統的 makefile 的樣子. 答案, 當然, 是內核建立系統處理 了余下的工作. 上面的安排( 它利用了由 GNU make 提供的擴展語法 )表明有一個模塊要 從目標文件 hello.o 建立. 在從目標文件建立后結果模塊命名為 hello.ko.

 

反之, 如果你有一個模塊名為 module.ko, 是來自 2 個源文件( 姑且稱之為, file1.c 和 file2.c ), 正確的書寫應當是:

 

obj-m := module.o

module-objs := file1.o file2.o

 

對於一個象上面展示的要工作的 makefile, 它必須在更大的內核建立系統的上下文被調用. 如果你的內核源碼數位於, 假設, 你的 ~/kernel-2.6 目錄, 用來建立你的模塊的 make 命令( 在包含模塊源碼和 makefile 的目錄下鍵入 )會是:

 

make -C ~/kernel-2.6 M=`pwd` modules

 

這個命令開始是改變它的目錄到用 -C 選項提供的目錄下( 就是說, 你的內核源碼目錄 ). 它在那里會發現內核的頂層 makefile. 這個 M= 選項使 makefile 在試圖建立模塊目標前, 回到你的模塊源碼目錄. 這個目標, 依次地, 是指在 obj-m 變量中發現的模塊列表, 在我 們的例子里設成了 module.o.

 

鍵入前面的 make 命令一會兒之后就會感覺煩, 所以內核開發者就開發了一種 makefile 方式, 使得生活容易些對於那些在內核樹之外建立模塊的人. 這個竅門是如下書寫你的 makefile:

 

# If KERNELRELEASE is defined, we've been invoked from the

# kernel build system and can use its language. ifneq ($(KERNELRELEASE),)

 

obj-m := hello.o

# Otherwise we were called directly from the command

# line; invoke the kernel build system.

 

else

 

KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

 

endif

 

再一次, 我們看到了擴展的 GNU make 語法在起作用. 這個 makefile 在一次典型的建立 中要被讀 2 次. 當從命令行中調用這個 makefile , 它注意到 KERNELRELEASE 變量沒有 設置. 它利用這樣一個事實來定位內核源碼目錄, 即已安裝模塊目錄中的符號連接指回內 核建立樹. 如果你實際上沒有運行你在為其而建立的內核, 你可以在命令行提供一個 KERNELDIR= 選項, 設置 KERNELDIR 環境變量, 或者重寫 makefile 中設置 KERNELDIR 的 那一行. 一旦發現內核源碼樹, makefile 調用 default: 目標, 來運行第 2 個 make 命 令( 在 makefile 里參數化成 $(MAKE))象前面描述過的一樣來調用內核建立系統. 在第 2 次讀, makefile 設置 obj-m, 並且內核的 makefile 文件完成實際的建立模塊工作.

 

這種建立模塊的機制你可能感覺笨拙模糊. 一旦你習慣了它, 但是, 你很可能會欣賞這種 已經編排進內核建立系統的能力. 注意, 上面的不是一個完整的 makefile; 一個真正的 makefile 包含通常的目標類型來清除不要的文件, 安裝模塊等等. 一個完整的例子可以參 考例子代碼目錄的 makefile.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM