linux核心模組編譯makefile

2022-07-04 07:33:09 字數 4001 閱讀 8419

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.o

all:

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檔案。

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/,指定核心原始碼的位置。

6、同時編譯多個可載入模組

當乙個.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 makefile

edit : 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...