1、編譯進核心的模組
如果需要將乙個模組配置進核心,需要在makefile中進行配置:obj-y += foo.o
2、編譯可載入的模組
所有在配置檔案中標記為-m的模組將被編譯成可載入模組.ko檔案。如果需要將乙個模組配置為可載入模組,需要在makefile中進行配置:
obj-m += foo.o
3、模組編譯依賴多個檔案
通常的,驅動開發者也會將單獨編譯自己開發的驅動模組,當乙個驅動模組依賴多個原始檔時,需要通過以下方式來指定依賴的檔案:obj-m +=foo.o
foo-y :=a.o b.o c.o
foo.o 由a.o,b.o,c.o生成,然後呼叫$(ld) -r 將a.o,b.o,c.o鏈結成foo.o檔案。
4、編譯選項
在核心態,編譯的選項由extra_cflags, extra_aflags和 extra_ldflags修改成了ccflags-y asflags-y和ldflags-y.ccflags-y asflags-y和ldflags-y這三個變數的值分別對應編譯、彙編、鏈結時的引數。
5、最簡單的makefile
obj-m+=hello.oall:
make -c /lib/modules/$(shell uname -r)/build/ m=$(pwd) modules
clean:
make -c /lib/modules/$(shell uname -r)/build/ m=$(pwd) clean
這個makefile的作用就是編譯hello.c檔案,最終生成hello.ko檔案。6、同時編譯多個可載入模組obj-m+=hello.o
obj-m表示編譯生成可載入模組。
相對應的,obj-y表示直接將模組編譯進核心。
obj-m+=hello.o,這條語句就是顯式地將hello.o編譯成hello.ko,而hello.o則由make的自動推導功能編譯hello.c檔案生成。
-c選項:此選項指定make在編譯時將會進入指定的目錄(核心原始碼目錄)。
modules是將原始檔編譯並生成核心模組。
$kdir:/lib/modules/$(shell uname -r)/build/,指定核心原始碼的位置。
當乙個.o目標檔案的生成依賴多個原始檔時,可以這樣指定:obj-m +=hello.o
hello-y :=a.o b.o hello_world.o
hello.o目標檔案依賴於a.o,b.o,hello_world.o,那麼這裡的a.o和b.o如果沒有指定原始檔,
根據推導規則就是依賴原始檔a.c,b.c,hello_world.c.
除了hello-y,同時也可以用hello-objs,實現效果是一樣的。
同時編譯多個可載入模組
kbuild支援同時編譯多個可載入模組,也就是生成多個.ko檔案,它的格式是這樣的:
obj-m :=foo.o bar.o
foo-y := bar-y := 就是這麼簡單。
7、ifneq ($(kernelrelease),)
通常,標準的makefile會寫成這樣:ifneq ($(kernelrelease),)
obj-m :=hello.o
else
kdir ?= /lib/modules/`uname -r`/build
all:
$(make) -c $(kdir) m=$(pwd) modules
clean:
$(make) -c $(kdir) m=$(pwd) clean
endif
為什麼要新增乙個ifneq,else,all條件判斷。
這得從linux核心模組make執行的過程說起:當鍵入make時,make在當前目錄下尋找makefile並執行,kernelrelease在頂層的makefile中被定義,
所以在執行當前makefile時kernelrelease並沒有被定義,走else分支,直接執行
$(make) -c $(kdir) m=$(pwd) modules
而這條指令會進入到$(kdir)目錄,呼叫頂層的makefile,在頂層makefile中定義了kernelrelease變數.
在頂層makefile中會遞迴地再次呼叫到當前目錄下的makefile檔案,這時kernelrelease變數已經非空,所以執行if分支,
在可載入模組編譯列表新增hello模組,由此將模組編譯成可載入模組放在當前目錄下。
歸根結底,各級子目錄中的makefile檔案的作用就是先切換到頂層makefile,然後通過obj-m在可載入模組編譯列表中新增當前模組,
kbuild就會將其編譯成可載入模組。
如果是直接編譯整個核心原始碼,就省去了else分支中進入頂層makefile的步驟。
需要注意的乙個基本概念是:每一次編譯,頂層makefile都試圖遞迴地進入每個子目錄呼叫子目錄的makefile,
只是當目標子目錄中沒有任何修改時,預設不再進行重複編譯以節省編譯時間。
8、標頭檔案的放置
當編譯的目標模組依賴多個標頭檔案時,kbuild對頭檔案的放置有這樣的規定:• 直接放置在makefile同在的目錄下,在編譯時當前目錄會被新增到頭檔案搜尋目錄。
• 放置在系統目錄,這個系統目錄是源**目錄中的include/linux/。
• 與通用的makefile一樣,使用-i$(dir)來指定,不同的是,代表編譯選項的變數是固定的,為ccflag.
• 一般的用法是這樣的:
ccflags-y := -i$(dir)/include
kbuild就會將$(dir)/includ目錄新增到編譯時的標頭檔案搜尋目錄中。
9、簡單使用者態makefile例項
#sample makefileedit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
Linux核心模組編譯
data mining linux核心模組是一種可被動態載入和解除安裝的可執行程式。通過核心模組可以擴充套件核心功能,核心模組通常用於裝置驅動 檔案系統等。如果沒有核心模組,需要向核心新增功能就需要自發 重新編譯核心 安裝新核心等步驟。核心空間中不止乙個程式試圖訪問驅動程式模組,導致乙個核心塊在沒有...
Linux編譯核心模組
核心模組即驅動的編譯方式 1 本地編譯 2 交叉編譯 makefile主要寫法 本地編譯 obj m hello.o kdir lib modules shell uname r build pwd shell pwd all make c kdir m pwd modules clean rm o...
linux核心模組編譯
1 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 ma...