好,进入正题,来看我们今天的要讲的Makefile:
ifneq ($(KERNELRELEASE),) obj-m := hello.o else KDIR := /home/friendly210/linux-3.8 all: make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux- clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif
上面这份Makefile是用来编译hello驱动的,是一份比较简单的Makefile。
1、ifneq () ... else.... endif : 条件语句,如果ifneq后面的值不相等,则执行接下来的语句,否则则执行else后面的语句。endif表示条件语句的结束,括号中传入两个参数值。和ifneq类似的条件语句还有ifeq, ifdef,ifndef。如果有一些C语言的基础,很容易理解这里的条件语句,看一下名字就能知道是干嘛的了。跟C语言的预编译语句基本相似。
2、KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,我们可以使用$(变量名)来获取变量的值。所以第一行意思就是:当KERNELRELEASE不为空时就执行obj-m := hello.o, 否则就执行else后面的语句。
3、obj-m 和KDIR 是定义的两个变量, 使用:= 来进行赋值,使用:= 赋值时,不能引用定义在其后面的变量。暂时先了解,以后会与其他赋值符号进行对比。
4. all和clean是两个label,当我们使用make all编译时就执行all标签后面的语句,clean也是同理。
5. make命令是用来编译的, -C表示切换目录,在寻找 Makefile 之前会切换到指定的目录目录。 M是makefile脚本中的一个变量,意思是返回到当前目录继续读入、执行当前的Makefile。 modules表示编译成模块, ARCH是一个变量,它用来表示编译目标的架构。CROSS_COMPILE用于指定make所使用的交叉编译工具。
6.clean后面是一条rm命令,就是删除所有编译生成的文件。
7.obj-m表示把该模块编译成单独的模块,就是编译成一个.ko的文件。可以通过insmod来挂接模块驱动。
8.make执行流程:当使用make进行编译时,一开始KERNELRELEASE还没有定义,所以跑到else,执行make命令,因为KDIR定义为kernel的根目录,所以跑到kernel根目录下找Makefile,此时KERNELRELEASE已经定义,所以obj-m := hello.o被执行,内核根据Kbuild语法编译出.ko文件。(Kbuild如何执行我们暂时不去关心,只要知道它会根据obj-m的定义去编译出.ko文件即可)
总结:这是一个编译驱动的通用模板,以后改一下obj-m的值就ok了,但是不是绝对喔,如果比较复杂的驱动,可就不好说了。O(∩_∩)O哈哈~。希望对你有所帮助。