4.5Makefile 文件
接前一小节的内容,继续介绍系统是如何一步一步编译出内核镜像的。
在这里仍然以 LEDS 小灯为例。
4.5.1 宏定义 LEDS_CTL 的使用
如下图所示,led 驱动属于字符驱动,字符驱动一般是在源码目录“drivers/char/”下。
如上图所示,这里要关注的文件只有框框中的三个“itop4412_leds.c”,
“itop4412_leds.o”,“Makefile”。
itop4412_leds.c :比较好理解,就是 led 驱动的源码
itop4412_leds.o :这个是生成最终 zImage 二进制的中间文件
Makefile :就是 Make 命令所需要的文件
这里不关心 itop4412_leds.c 中的代码,只需先知道 itop4412_leds.c 的文件名即可。在源码目录中使用命令“vim drivers/char/Makefile”,如下图所示。
打开“vim drivers/char/Makefile”文件之后,找到和 itop4412_leds.c 相关的文件,搜索“itop4412_leds”,如下图所示。
如上图方框所示,就是编译 itop4412_leds.c 的脚本。这个脚本大家也只需要仿照写即可,严格的按照已有的例子来写即可。
如果想添加类似的字符驱动,就可以在这个目录下添加。
Kconfig、Makefile、menuconfig、“.config”文件大家就可以联系起来了。
4.5.2 Makefile 脚本语法简介
本小节介绍的语法是对内核源码子目录中 Makefile 进行简单的介绍,这部分是经常会用到的,也是需要掌握的。
常用的强制编译写法,还是在“drivers/char/Makefile”中,在 Top 行,如下图所示。
上图中的这一行“obj-y += misc.o”,注意这里需要和内核自带的代码对齐。
“加等号”右边的“misc.o”表示要编译 Makefile 目录下的“misc.c”文件,
“加等号”左边的“obj-y ”表示要编译,并链接进内核(链接进内核是 linux 源码中自带的工具处理的,驱动工程师完全不用关心具体是怎么实现的)
如下图所示,就是 LEDS_CTL 的条件编译,也就是需要在 Kconfig 中定义,在menuconfig 中配置之后,编译器运行的时候找到对应的宏变量 LEDS_CTL 之后才会编译。
上图比较好理解,因为一直是以这个 LEDS_CTL 为例来讲解的。这种方式在写驱动的时候会经常使用到。
最后介绍一下目录层次的迭代,如下图所示,使用命令“vim drivers/Makefile”打开“drivers/char”上一层目录的 Makefile 文件。
搜索关键词“char”,因为前面介绍到的字符变量在“char”目录下,如下图所示。
上图中的语法也是很简单,只不过“加等号”右边有文件变为了文件夹。这里表示强制编译当前目录“/drivers”的下一级目录“/char”。在执行编译命令执行到这句的时候,就会先跳转到“/char”目录下的“Makefile”文件。
4.6 Makefile 测试
本小节给大家做个简单的小实验,通过配置 menuconfig 中的 LEDS,来将内核编译进内核或者不编译进内核。
4.6.1 将 LEDS 驱动不编译
进内核如下图所示,在给大家提供的源码中,解压之后默认状态就有将“itop4412_leds.c”编译进内核的中间文件“itop4412_leds.o”,如下图所示。
如下图所示,使用命令“rm -rf drivers/char/itop4412_leds.o”删除掉 LEDS 驱动的中间文件“itop4412_leds.o”。
如下图所示,使用命令“ls drivers/char/”查看一下,发现已经没有了“itop4412_leds.o”文件。
然后使用命令“make menuconfig”,打开配置工具,如下图所示。
打开之后,如下图所示。找到“Device Drivers ---> ”选项。
如下图所示,进入到“Device Drivers ---> ”选项,找到选项“Character devices--->”。
如下图所示,找到选项“Enable LEDS config”,将 LEDS 的配置关闭
退出,保存,生成新的“.config”文件。
保存退出后,打开“.config”文件,可以发现“CONFIG_LEDS_CTL”没有配置。
关闭“.config”文件,然后执行编译内核的命令“make”,如下图所示。
如下图所示,编译完成。
如下图所示,使用命令“ls drivers/char”查看 LEDS 驱动所在目录,发现并没有产生了中间文件。
最后也可以将生成的文件“zImage”文件下载到开发板,会发现“/dev”目录中没有产生 LEDS 驱动的设备节点“leds”。
4.6.2 将 LEDS 驱动编译进内核
接上一小节,如下图所示,使用命令“make menuconfig”,打开 menuconfig 配置工具。
进入“ Device Drivers --->”选项,然后进入“Character devices --->”选项,然后如下图所示,配置上“Enable LEDS config”。
保存退出。打开“.config”文件,可以发现“CONFIG_LEDS_CTL=y”已经配置。
执行编译命令“make”,如下图所示,编译完成之后,使用命令“ls drivers/char/”可以看到“itop4412_leds.o”已经生成。
最后也可以将生成的文件“zImage”文件下载到开发板,会发现“/dev”目录中产生LEDS 驱动的设备节点“leds”,LED 灯的控制又恢复正常了。
4.7 编译流程图解
现在内核编译相关的知识已经全部介绍完,本节做一个小节。
下图已经将内核编译的全部过程包含。
如上图所示。
红色的线条表示配置文件 Kconfig 这一部分,在 Kconfig 中要定义针对具体驱动文件的宏变量。然后使用 menuconfig 工具生成新的”,config“文件。
黑色的线条表示编译文件 Makefile 这一部分,在 Makefile 中针对宏变量编译驱动文件。
执行 make 命令之后,调用“.config”文件,配合各级目录中的 Makefile 文件编译具体的驱动源代码,将源代码编译成“.o”中间文件。
当中间文件全部编译完成之后,编译工具会生成一个非常精炼的“zImage”二进制文件。
|