在寫驅動模組的makefile是通常都是找乙個現成的makefile修改一下就可以了,該文章主要是為了弄清楚驅動程式的makefile的原理。
例:乙個簡單的hello核心模組的makefile:
#hell0_makefile
ifneq ($(kernelrelease),)
obj-m:=hello.o
else
kerneldir:=/lib/modules/$(shell uname -r)/build
pwd:=$(shell pwd)
default:
$(make) -c $(kerneldir) m=$(pwd) modules
clean:
rm -rf *.o *.mod.c *.mod.o *.koendif
當我們在寫完乙個模組的makefile之後,只需要在當前目錄下進行make即可。那麼make的過程是怎樣的呢?
1.首先make時,由於make後面沒有目標,所以make會將default作為預設的目標檔案進執行。
make會執行$(make) -c $( kerneldir) m= $(pwd) modules,
#展開為:
make -c /lib/modules/2.6.13-study/build m=/home/study/hello/ modules
可見,make執行了兩次。第一次執行時是讀hello模組的源**所在目錄/home/study/hello/下的makefile,第二次執行時是執行/usr/src/linux/下的makefile時。
第一次make的時候,kernelrelease未定義,所以走else的分支,進入kernel目錄去編譯;進入kernel目錄編譯的時候會根據m= $ (pwd) 去$m目錄去編譯,也就是你make時所在的目錄;這時,kernelrelease是被定義過的,所以第二次會走obj-m:=hello.o分支,根據kernel的makefile中指定的規則,會把當前目錄下的hello.c編譯成hello.o然後生成對應的hello.ko,也就是核心模組。
但是,還是有很多問題
1.kernelrelease並未在驅動的makefile中定義,那它的作用是什麼?
makefile中是沒有定義這個變數的,所以起作用的是else…endif這一段。不過,如果把hello模組移動到核心源**中。例如放到/usr/src/linux/driver/中, kernelrelease就有定義了。 在/usr/src/linux/makefile中有 kernelrelease 的定義,這時候,hello模組也不再是單獨用make編譯,而是在核心中用make modules進行 編譯。 用這種方式,該makefile在單獨編譯和作為核心一部分編譯時都能正常工作。
2.obj-m := hello.o什麼時候執行?
在執行:make -c /lib/modules/2.6.13-study/build m=/home/study/prog/mod/hello/ modules時,make 去/usr/src/linux/makefile中尋找目標modules:
862 .phony: modules
863 modules: $(vmlinux-dirs) $(if $(kbuild_builtin),vmlinux)
864 @echo ' building modules, stage 2.';
//呼叫makefile.modpost進行第二階段模組編譯
865 $(q)$(make) -rr -f $(srctree)/scripts/makefile.modpost
可以看出,分兩個stage:
1.編譯出hello.o檔案。
2.生成hello.mod.o hello.ko
在這過程中,會呼叫 make -f scripts/makefile.build
obj = /home/study/hello
而在 scripts / makefile.build會包含很多檔案: include .config include $(if $(wildcard $(obj)/kbuild), $(obj)/kbuild, $(obj)/makefile) 其中就有/home/study/hello/makefile 這時 kernelrelease已經存在。 所以執行的是: obj-m:=hello.o
ps:關於make modules的更詳細的過程可以在scripts/makefile.modpost檔案的注釋 中找到。如果想檢視make的整個執行過程,可以執行make -n。
linux 驅動程式 高階字元驅動程式
ioctl方法 驅動程式的原型實現 int ioctl struct inode inode,struct file filp,unsigned int cmd,unsigned long arg ioctl 命令選擇 位段結構 number direction ioc read ioc write...
linux裝置驅動程式 字元裝置驅動程式
先留個 有一起學習驅動程式的加qq295699450 字元裝置驅動 這篇比較惱火。載入成功,但是讀不出來資料,有知道怎麼回事的,留個言,一起討論下 資料結構 struct scull mem struct scull dev dev 整個驅動程式 如下 include include include...
Linux裝置驅動程式 字元裝置驅動程式
1.檢視主裝置號,次裝置號 進入 dev目錄執行ls l,第四,五列分別為主次裝置號,10,180,1,5,這些是主裝置號,而60,63這些就是次裝置號 130 shell android dev ls l crw rw r system radio 10,60 1969 12 31 21 00 a...