内核中那些文件将被编译?他们是怎样被编译的?他们连接时顺序如何确定?那个文件在最前面?内核最先执行的文件怎样确定?这些都是通过Makefile来管理的。
a)顶层Makefile它是所有Makefile文件的核心,从总体上控制内核编译,连接
b).config配置文件(make menuconfig内核配置完之后自动生成),所有Makefile文件都是根据.config来确定使用那些文件的
c)arch/$(ARCH)/Makefile对应体系的Makefile(如arch/arm/Makefile),它用来决定那些体系结构相关的文件参与内核的生成,并提供一些规则来生成特定格式的内核镜像
d)各级目录下的Makefile文件,它们被上一层Makefile调用来编译当前目录下文件
接下来看一下内核顶层的Makefile内容如下:
可以看到顶层Makefile将14个目录分成5类:init-y ,drivers-y,net-y ,libs-y,
core-y,除去include和arch目录没有包含进来,arch在arch/$(ARCH)/Makefile中被包含进内核如下
441 include $(srctree)/arch/$(SRCARCH)/Makefile
在arch/arm/Makefile下可以看到
183 core-y
184 core-y
185 core-$(CONFIG_FPE_NWFPE)
186 core-$(CONFIG_FPE_FASTFPE)
187 core-$(CONFIG_VFP)
188
189 drivers-$(CONFIG_OPROFILE)
190
191 libs-y
94行那里除了前面5类子目录又多了一种head-y,不过他直接以文件名出现,对于arm处理器$(MMUEXT)为空,通过分析可知内核执行的第一个文件就是arch/arm/kernel/head.S(可以看我的另一篇博文)。
当我们编译内核时,将依次进入init-y ,drivers-y,net-y ,libs-y,core-y所列出的目录执行他们的Makefile,每个子目录都会生成一个built-in.o(libs所列目录下有可能生成lib.a文件),最后head-y所表示的文件和这些built-in.o,lib.a一起连接成内核镜像文件vmlinux.
在顶层Makefile中可以看到如下
第672行的vmlinux-all表示构成内核镜像文件的vmlinux的目标文件,这里就不展开各个文件了,可以看我另一篇博文,从中可以知道这些目标文件的顺序为head-y,init-y,core-y,libs-y,net-y.
具体怎样连接要看内核连接脚本,对于arm体系连接脚本就是arch/arm/kernel/vmlinux.lds,它由arch/arm/kernel/vmlinux.lds.S文件生成。
最后还看一下在顶层Makefile中的
上面的patsubst是个字符串处理函数,进行了上面转换之后init-y变成init/built-in.o,表示要连接进内核,其它的一样。
上面说的主要是顶层Makefile下面说一下各个目录下的Makefile这个相对来说简单一点
就像上面列出的一样,直接把文件名*.c在Makefile中按照一定格式改成*.o就可以了,最后编译完之后会生成一个*.o文件和一个built-in.o
下面分析一下内核Kconfig
linux内核中所有配置工具都是通过读取arch/arm/Kconfig文件来生成配置界面的,这个文件是所有配置文件的入口,它会包含其他目录的Kconfig文件进来。
我们内核中每个子目录中都会有一个Makefile和Kconfig文件,每个目录下的Kconfig文件是配置界面的源文件。
下面我们来看一下arch/arm/Kconfig文件,看看他是怎样包含别的Kconfig文件的
其中source表示包含后面目录的Kconfig,这样我们就可以把分散在其它目录Kconfig组合在一次了
下面来看一下Kconfig中每个菜单是怎样生成的
Kconfig文件的基本要素config条目,config条目是用来生成菜单的,通常被其它条目包含
其中config为关键字,表示一个配置项开始,接着的是MFD_SM501_GPIO配置项名称也就是我们在.config中看到的项,这里省略了CONFIG_,第23行bool表示变量类型,在Kconfig中变量类型主要有bool,tristate,string,hex,int,其中tristate,string是两种基本类型,bool变量取值为两种y和n,tristate为三种y,m,n,bool之后就是字符串提示信息也就是我们在配置是看到的名称,
depends on表示依赖关系例子中表示依赖MFD_SM501
default y 表示默认值为y
"select" <symbol>选择关系也就是A如果选了B,在A被选中的时候B自动选中
"prompt" <prompt>提示信息
help帮助信息
下面再来介绍一下menu条目
menu条目用于生成菜单
menu "Floating point emulation"
config FPE_NWFPE
config FRE_NEFPE_XP
....
endmenu
menu...endmenu中可以包含很多config条目,它相当于一个大的菜单
还有choice...endchoice也一样这个是将多个类似的菜单放在一次和menu格式差不多
...
endchoice
comment条目是定义一些帮助信息,这里就不说了
下面通过一个例子来说明Kconfig和Makefile的关系
假设我们要在源码目录drivers目录下增加一个test目录里面内容只有一个myleds.c文件
这时我们要做的就是在这个目录里增加Makefile和Kconfig使运行make menuconfig时能进行菜单选择
在新增的test目录下,Kconfig如下
为了这个Kconfig起作用,我们还要修改arch/arm/Kconfig文件,增加
source "drivers/test/Kconfig"
下面是test目录Makefile文件
为了能编译到test目录父目录下Makefile要新增内容如下:
obj-y += test/
这样就可以了
到了这里Makefile和Kconfig就分析完了