您好,登錄后才能下訂單哦!
這篇文章主要介紹linux怎么在2.6內核中編譯內核模塊,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
編譯內核模塊的方法與編譯一般應用程序的方法略有不同. 我們會發現在內核源碼樹的層層目錄中, 都存在有Makefile. 即這些Makefile是分層次組織的. 以往的內核版本中, 編譯內核模塊比較麻煩, 需要我們對這些Makefile做出許多更改. 2.6的內核采用了"kbuild"編譯系統, 簡化了這些問題. 關于kbuild, 可參考內核源碼樹中的 /Documentation/kbuild/modules.txt.
編譯之前, 肯定是需要源文件的. 這些源文件可以放在內核源碼樹中, 也可以放在內核源碼樹之外的任何地方. 根據源文件存在的目錄, 存在兩種編譯方法: 在源碼樹之中和在源碼樹之外.
在源碼樹中編譯模塊
官方內核模塊的源代碼都是按模塊(驅動)類型組織的, 我們到內核源碼樹的drivers目錄可以看到char, usb, block之類的子目錄. 那么我們在內核源碼樹中添加文件時, ***也遵循這些分類. 分類的規則自己靈活把握.
下面以前面的"hello, world"這個簡單的模塊為例, 來看看如何在內核源碼樹中編譯內核模塊.
1, 不新建子目錄
(1) 先在內核源碼樹中的drivers目錄編輯一個c源程序, 名為hello.c.
(2) 修改drivers目錄的Makefile文件, 添加: obj-m += hello.o
(3) 重新編譯內核(回到源碼樹根目錄, 運行 $ sudo make).
這樣, 在drivers目錄多出了這樣幾個文件: hello.mod.c, hello.mod.o, hello.o, hello.ko. hello.ko就是編譯出來的模塊了.
2, 新建子目錄
如果源文件比較多, 可以在drivers目錄中新建子目錄. 還是以hello, world為例:
(1) 在內核源碼樹的drivers目錄中新建一個hello子目錄, 并將hello.c放在hello目錄中.
(2) 修改drivers目錄的Makefile文件, 添加: obj-m += hello/
(3) 在hello目錄中新建一個Makefile文件, 內容為: obj-m += hello.o
(4) 重新編譯內核(回到源碼樹根目錄, 運行 $ sudo make).
這樣, 新生成的模塊文件就位于hello目錄中.
若在內核源碼樹中編譯內核模塊, 如果不新建子目錄, 那么只需修改當前目錄的Makefile, 否則應該在當前新建的子目錄中新建Makefile指定編譯選項, 并修改上層目錄的Makefile以讓kbuild能夠進入新建的子目錄.
在源碼樹之外編譯模塊
還是以上面的hello, world為例. 在當前目錄有個hello.c:
(1)首先在模塊代碼所在的目錄新建一個Makefile, 內容為:
obj-m := hello.o
(2)這樣調用make命令:
$ sudo make -C /usr/local/src/kernel/linux-2.6.16.20 SUBDIRS=$PWD modules
這里/usr/local/src/kernel/linux-2.6.16.20是內核源碼樹所在的目錄.
-C表示要求make先切換到-C指定的目錄. SUBDIRS(也可以用M代替SUBDIRS)使make在編譯內核模塊之前回到當前目錄.
整個編譯過程實際上是執行-C指定的內核源碼樹的Makefile, 并通過SUBDIR指定你要編譯的內核源文件的目錄.
簡化命令行輸入
每次調用make的時候輸入這些參數比較比較麻煩, 可以這樣來改寫Makefile以簡化:
obj-m += hello.oall: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
這樣, 只需在當前目錄調用 $ sudo make 就可以完成上面的工作. 調用 $ sudo make clean 將刪除所有新生成的文件.
上面的Makefile是這樣確定內核源碼樹所在的目錄的: 我們先到/lib/modules目錄, 會看到一些以內核版本為名的目錄, 目錄中有一個build文件, 它是一個符號連接, 指向內核源碼樹. 那么如何確定進入哪個內核版本的目錄呢? 這就可以通過 $ uname -r 來確定, 它指出了當前運行內核的版本.
還可以進一步簡化這個Makefile:
obj-m := hello.o KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
這樣不用在Makefile中一次又一次地指定內核代碼樹的目錄.
上面的例子中只討論了所有的代碼在一個文件中的情況. 若代碼分布在多個源文件中, 比如file1.c, file2.c, 生成hello.ko. 應該這樣寫Makefile:
obj-m := hello.o
hello-objs := file1.o file2.o
注意, 雖然我們的目的是生成.ko文件, 但在Makefile中寫為.o!
以上是“linux怎么在2.6內核中編譯內核模塊”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。