目標定義:就是用來定義哪些內容作為模塊編譯,哪些內容要編譯並鏈接進內核。
obj-y += foo.o 表示要由foo.c或者foo.s文件編譯得到foo.o並鏈接進內核;
obj-m則表示該文件要作為模塊編譯。
簡潔版
1 #General Purpose Makefile for Linux Kernel module by guoqingbo 2 3 KERN_DIR = /home/gaoxingpeng/dm365/dvsdk_dm365_4_02_00_06/psp/linux-2.6.32.17-psp03.01.01.39
4 #KERN_DIR = /usr/src/$(shell uname -r)
5 #KERN_DIR = /lib/modules/$(shell uname -r)/build
6
7 all:
8 make -C $(KERN_DIR) M=$(shell pwd) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
9 10 clean: 11 make -C $(KERN_DIR) M=$(shell pwd) modules clean 12 rm -rf modules.order 13 14 obj-m += xxx.o
第3行KERN_DIR表示內核源碼目錄,這種方式適用於嵌入式開發的交叉編譯,KERN_DIR目錄中包含了內核驅動模塊所需要的各種頭文件及依賴。若在PC機開發內核模塊則應使用第4、5行的寫法。
第8行中-C表示 指定進入指定的目錄即KERN_DIR,是內核源代碼目錄,調用該目錄頂層下的Makefile,目標為modules。
M=$(shell pwd)選項讓該Makefile在構造modules目標之前返回到模塊源代碼目錄並在當前目錄生成obj-m指定的xxx.o目標模塊。
clean這個目標表示將模塊清理掉
obj-m += xxx.o即指定當前目錄要生成的目標模塊,然后modules目標指向obj-m變量中設定的模塊
通用規范版
1 # Makefile2.6 2 ifneq ($(KERNELRELEASE),) 3 #kbuild syntax. dependency relationshsip of files and target modules are listed here. 4 5 mymodule-objs := hello.o 6 obj-m := hello.o 7 8 else 9 PWD := $(shell pwd) 10 11 KVER ?= $(shell uname -r) 12 KDIR := /lib/modules/$(KVER)/build #KDIR目錄其實是鏈接到上面那個Makefile中的那個 13 /usr/src/linux-source-2.6.15/*中 14 all: 15 $(MAKE) -C $(KDIR) M=$(PWD) 16 17 clean: 18 rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions 19 20 endif
KERNELRELEASE 是在內核源碼的頂層Makefile中定義的一個變量,在第一次讀取執行此Makefile時,KERNELRELEASE沒有被定義,所以make將讀取執行else之后的內容。
當make的目標為all時,-C $(KDIR) 指明跳轉到內核源碼目錄下讀取那里的Makefile;M=$(PWD) 表明然后返回到當前目錄繼續讀入、執行當前的Makefile。
當從內核源碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啟動去解析kbuild語法的語句,make將繼續讀取else之前的內容。else之前的內容為kbuild語法的語句, 指明模塊源碼中各文件的依賴關系,以及要生成的目標模塊名。
每個內核的名字都包含了它的版本號,這也是 uname -r 命令顯示的值。
關於報以下錯誤的解決方法:
Makefile:1: *** 遺漏分隔符
這個有多種情況:
1,命令前要加tab鍵
2,可能標點符號輸成中文形的了
3,比如上面那個文件:ifneq后面要加個空格
對於模版的使用,我們需要修改的地方三處:
1:目標文件;
2:內核源碼目錄
3:編譯器(版本不同)
https://blog.csdn.net/lqjun/article/details/49338845
https://blog.csdn.net/lufeiop02/article/details/6446343