您的位置:首页 > 运维架构 > Linux

一步一步学习Linux驱动之驱动模块MakeFile解析

2015-04-13 09:25 155 查看
<span style="background-color: rgb(245, 245, 245); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。</span>


一、使用条件判断

下面的例子,判断$(CC)变量是否“gcc”,如果是的话,则使用GNU函数编译目标。

libs_for_gcc = -lgnu 
normal_libs = 

foo: $(objects) 
ifeq ($(CC),gcc) 
     $(CC) -o foo $(objects) $(libs_for_gcc) 
else 
     $(CC) -o foo $(objects) $(normal_libs) 
endif


可见,在上面示例的这个规则中,目标“foo”可以根据变量“$(CC)”值来选取不同的函数库来编译程序。

我们可以从上面的示例中看到三个关键字:ifeq、else和endif。ifeq的意思表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起。else表示条件表达式为假的情况。endif表示一个条件语句的结束,任何一个条件表达式都应该以endif结束。

libs_for_gcc = -lgnu 
normal_libs = 

ifeq ($(CC),gcc) 
    libs=$(libs_for_gcc) 
else 
    libs=$(normal_libs) 
endif 

foo: $(objects) 
     $(CC) -o foo $(objects) $(libs)
下面是关于一段arm驱动程序的分析
obj-m :=hello.o

KERNELDIR :=/home/ZP1015/Desktop/linux-2.6.32.2

all:
	 make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
	rm -f *.o *.ko *.mod.o *.mod.c *.symvers modul*


ifneq ($(KERNELRELEASE),)

obj-m :=hello.o

else

KERNELDIR :=/home/ZP1015/Desktop/linux-2.6.32.2

all:
	 make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
	rm -f *.o *.ko *.mod.o *.mod.c *.symvers modul*

endif


1、ifeq”语法是ifeq (<arg1>;, <arg2>;),功能是比较参数“arg1”和“arg2”的值是否相同。ifneq刚好相反,比较两者的值是否不同其中有一些是我们常见或是见过的,第一个ifneq
($(KERNELRELEASE),)目前,有用处,它的由来是指在Linux源码根目录下的Makefile编译内核时,KERNELRELEASE宏会被定义,那么如果是从源码根目录开始的make则会将hello.o模块编译进内核。

KERNELDIR
:=/home/ZP1015/Desktop/linux-2.6.32.2 这句是对KERNELDIR进行赋值,这个变量是后面我们用到的指代内核源码目录用的。

2、make
-C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-

这句是Makefile的规则:这里的$(MAKE)就相当于make,-C 选项的作用是指将当前工作目录转移到你所指定的位置。“M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make
modules 命令中加入“M=dir”,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件。M不是makefile的选项,是内核根目录下的Makefile中使用的变量

3、具体编译过程

KERNELRELEASE:由Kernel顶层Makefile中定义。

判断变量KERNELRELEASE与空字符是否相同,即判断变量KERNELRELEASE的值是否为空,为空的话就进入else

第一次运行中,KERNELRELEASE没有被定义,所以进入else

$(MAKE) -C $(KERNELDIR) M=$(PWD)

此处读取KERNELDIR中的顶层Makefile。读取后又返回本目录。继续执行本目录Makefile。

则此时KERNELRELEASE被定义。进入if.

if和else之间的为kbuild语法的语句.

4、两段makefile对比分析

如何内核源码路径设置正确,其实两段makefile没有什么区别,作用完全一致。但是有用ifneq之后,可以确保是从内核构造系统调用的。如果内核源码路径设置错误,KERNELRELEASE没有定义,make就没有对象。所以建议用后面那段makefile
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐