模組-kernel 模組編譯(Makefile編寫)
阿新 • • 發佈:2019-01-26
發現自己以前寫的2.4的模組無法在2.6下面編譯使用了,需要用新的Makefile才行。簡單的說就像這個樣子:
obj-m := mytest.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
就可以了,模組的名稱是mytest,最後編譯出來是mytest.ko,剩下的系統搞定。當然這裡有一些隱含規則了,就是mytest.o由
mytest.c或者mytest.S編譯出來。如果模組是由多個原始檔搞定的,那麼建議去參考
~linuxsrc/Documentation/kbuild/下的一些文件。
--- add on 2005年11月16日 ---
如果是多個原始檔編譯出一個模組,那麼假設模組名是mytest.ko,那麼原始檔名不能有mytest.c,下面是一個例子:
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
這裡比較奇怪的是makefile裡面沒有用SUBDIRS=,而是用了M=
--- end of add on 2005年11月16日 ---
--- add on 2006年5月20日 ---
關於前面的makefile當中用M=代替SUBDIR=,效果是一樣的,但是M=更明確,參見《從 2.4 到 2.6:Linux 核心可裝載模組機制的改變對裝置驅動的影響》
http://www-128.ibm.com/developerworks/cn/linux/l-module26/
對於Makefile,其中建議為(將上面的改成):
ifneq ($(KERNELRELEASE),)
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
解釋為:
KERNELRELEASE
是在核心原始碼的頂層Makefile中定義的一個變數,在第一次讀取執行此Makefile時,KERNELRELEASE沒有被定義,
所以make將讀取執行else之後的內容。如果make的目標是clean,直接執行clean操作,然後結束。當make的目標為all時,-C
$(KDIR) 指明跳轉到核心原始碼目錄下讀取那裡的Makefile;M=$(PWD)
表明然後返回到當前目錄繼續讀入、執行當前的Makefile。當從核心原始碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啟動去
解析kbuild語法的語句,make將繼續讀取else之前的內容。else之前的內容為kbuild語法的語句,
指明模組原始碼中各檔案的依賴關係,以及要生成的目標模組名。mytest-objs := file1.o file2.o
file3.o表示mytest.o 由file1.o,file2.o與file3.o 連線生成。obj-m :=
mytest.o表示編譯連線後將生成mytest.o模組。
--- end of add on 2006年5月20日 ---
另外,編譯完核心以後用make INSTALL_MOD_PATH=/pathyouwant modules_install可以把核心模組裝到指定目錄
obj-m := mytest.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
就可以了,模組的名稱是mytest,最後編譯出來是mytest.ko,剩下的系統搞定。當然這裡有一些隱含規則了,就是mytest.o由
mytest.c或者mytest.S編譯出來。如果模組是由多個原始檔搞定的,那麼建議去參考
~linuxsrc/Documentation/kbuild/下的一些文件。
--- add on 2005年11月16日 ---
如果是多個原始檔編譯出一個模組,那麼假設模組名是mytest.ko,那麼原始檔名不能有mytest.c,下面是一個例子:
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
這裡比較奇怪的是makefile裡面沒有用SUBDIRS=,而是用了M=
--- end of add on 2005年11月16日 ---
--- add on 2006年5月20日 ---
關於前面的makefile當中用M=代替SUBDIR=,效果是一樣的,但是M=更明確,參見《從 2.4 到 2.6:Linux 核心可裝載模組機制的改變對裝置驅動的影響》
http://www-128.ibm.com/developerworks/cn/linux/l-module26/
對於Makefile,其中建議為(將上面的改成):
ifneq ($(KERNELRELEASE),)
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
解釋為:
KERNELRELEASE
是在核心原始碼的頂層Makefile中定義的一個變數,在第一次讀取執行此Makefile時,KERNELRELEASE沒有被定義,
所以make將讀取執行else之後的內容。如果make的目標是clean,直接執行clean操作,然後結束。當make的目標為all時,-C
$(KDIR) 指明跳轉到核心原始碼目錄下讀取那裡的Makefile;M=$(PWD)
表明然後返回到當前目錄繼續讀入、執行當前的Makefile。當從核心原始碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啟動去
解析kbuild語法的語句,make將繼續讀取else之前的內容。else之前的內容為kbuild語法的語句,
指明模組原始碼中各檔案的依賴關係,以及要生成的目標模組名。mytest-objs := file1.o file2.o
file3.o表示mytest.o 由file1.o,file2.o與file3.o 連線生成。obj-m :=
mytest.o表示編譯連線後將生成mytest.o模組。
--- end of add on 2006年5月20日 ---
另外,編譯完核心以後用make INSTALL_MOD_PATH=/pathyouwant modules_install可以把核心模組裝到指定目錄