Linux内核Makefile

注:以下文字大部分来自韦东山《嵌入式Linux应用开发完全手册》


Linux内核源码中含有很多个Makefile文件主要分为以下5类:

                                        Linux内核Makefile文件分类

顶层Makefile

根据不同的平台,对各类target分类并调用相应的规则Makefile生成目标

.config

内核配置文件

arch/$(ARCH)/Makefile 

具体平台相关的Makefile

scripts/Makefile.*

通用规则文件,面向所有的Kbuild Makefiles,所起的作用可以从后缀名中得知。

各子目录下的Makefile 文件

由其上层目录的Makefile调用,执行其上层传递下来的命令


Linux的Makefile有三个作用:

1.决定编译那些文件;

2.怎样编译这些文件;

3.怎样连接这些文件,最重要的是它们的顺序如何;


1.决定编译那些文件:

Linux内核的编译过程从顶层Makefile开始,然后递归地进入各级子目录调用它们的Makefile,分为3个步骤:

1)顶层Makefile决定内核目录下哪些子目录将被编进内核。

2)arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下哪些文件、哪些目录将被编进内核。

3)各级子目录下的Makefile决定所在目录下哪些文件将被编进内核,哪些文件将被编进模块(说的是驱动程序),进入哪些子目录继续调用它们的Makefile。


先看步骤1),在顶层Makefile中可以看到如下内容:

433 init-y := init/
434 drivers-y := drivers/ sound/
435 net-y := net/
436 libs-y := lib/
437 core-y := usr/

556 core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/


可见,顶层Makefile将内核源码目录下的13个子目录分为5类:init-y、drivers-y、net-y、libs-y、core-y。(core-y包含了kernel、mm、fs、ipc、security、crypto、block,共7个文件夹)。内核源码目录下有17个子目录,除去include目录和后面两个不包含内核代码的目录外,还有一个arch目录没有出现在内核中。它在arch/$(ARCH)/Makefile中被包含进内核,在顶层Makefile中直接包含了这个Makefile,如下所示:

491 include $(srctree)/arch/$(ARCH)/Makefile

对于上面出现的ARCH变量,可以在执行make命令传入,比如“make ARCH=arm...”。另外,对于非x86平台,还需要指定交叉编译工具,这也可以在执行make命令时传入,比如“make CROSS_COMPILE=arm-linux-...”。为了方便,常在Makefile中进行如下修改:

修改前:

185 ARCH?= $(SUBARCH)
186 CROSS_COMPILE ?=

修改后:

185 ARCH?= arm
186 CROSS_COMPILE ?=arm-linux-


再来看步骤2),在arch/arm/Makefile中可以看到如下内容:

94 head-y:= arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

171 core-y+= arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
172 core-y += $(MACHINE)
173 core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
174 core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
175 core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/

191 libs-y:= arch/arm/lib/ $(libs-y)

    从第94行可知,除前面的5类子目录外,又出现了另一类:head-y,不过它直接以文件名出现。其中的MMUEXT在arch/arm/Makefile前面定义,对于没有MMU的处理器,MMUEXT的值为-nommu,使用文件head-nommu.s;对于有MMU的处理器,MMUEXT的值为空,使用文件head.s。

    arch/arm/Makefile中的171、172、173等行代码进一步扩展了core-y的内容,第191行扩展了lib-y的内容,这些都是体系结构相关的目录。第173~175行中的CONFIG_ARCH_S3C2410在配置内核时定义,它的值有三种:y、m和空。y表示编进内核,m表示编为模块,空表示不使用。

    编译内核时,将依次进入inti-y、core-y、lib-y、drivers-y和net-y所列出的目录中执行它们的Makefile,每个子目录都会生成一个built-in.o(在lib-y所列的目录下,有可能生成lib.a文件)。最后head-y所表示的文件将和这些built-in.o、lib.a一起被连接成内核映像文件vmlinux。

    最后,看一下步骤3),各子目录的Makefile怎么进行的。

    在配置内核后,将会生成配置文件.config。内核使用语句

441 #Read in config

442 -include include/config/auto.conf

间接包含了.config文件,然后就根据.config中定义的各个变量决定编译哪些文件。

之所以说是间接,是因为包含的是auto.conf,而auto.conf是将.config中的注释去掉,再根据顶层Makefile中定义的变量增加了一些变量的文件。

auto.conf的格式与.config相同,下面是一个片段:

CONFIG_ARCH_SMDK2410=y

CONFIG_ARCH_S3C2440=y

#.config中没有下面这行,它是根据顶层Makefile中定义的内核版本号增加的

CONFIG_KERNELVERSION="2.6.22.6"

#.config中没有下面这行,它是根据Makefile中定义的ARCH变量增加的

CONFIG_ARCH="arm"

CONFIG_JFFS2_FS=y

CONFIG_LEDS_S3C24XX=m


在include/configauto.conf文件中,变量的值主要有两类:“y”和“m”。各级子目录的Makefile使用这些变量来决定哪些文件被编进内核,哪些被编为模块。

要进入哪些下一级子目录继续编译,通过下面4中方法来确定(obj-y、obj-m、lib-y都是Makefile中的变量)

1))obj-y决定哪些文件被编进(built-in)内核

    obj-y中定义的.o文件由当前目录下的.c或.s文件编译生成,它们连同下级子目录的built-in.o文件一起被组合成(使用“$(LD) -r”命令)当前目录下的built-in.o文件。这个built-in.o将被它上一层的Makefile使用。

    obj-y中各个.o文件是有顺序的,因为内核中用module_init()或_initcall定义的函数将按照它们的连接顺序被调用。

2))obj-m用来定义哪些文件将被编译成可加载模块

    obj-m中定义的.o文件由当前目录下的.c或.s文件编译生成,它们不会被编进built-in.o中,而是被编程可加载模块。

3))lib-y用来定义哪些文件被编成库文件

    lib-y中定义.o文件由当前目录下的.c或.s文件编译生成,它们被打包成当前目录下的一个库文件:lib.a

    要把这个lib.a编进内核,需要在顶层Makefile中lib-y变量中列出当前目录。要编成库文件的内核代码一般都在这两个目录下:lib/、arch/$(ARCH)/lib/

4))obj-y、obj-m还可以用来指定要进入的下一层目录。


2.怎样编译这些文件



3.怎样连接这些文件,它们的顺序如何

顶层Makefile和arch/$(ARCH)/Makefile中定义了6类目录:head-y、init-y、drivers-y、net-y、libs-y和core-y。


可见,出head-y外,其余都是目录名。在顶层Makefile中,这些目录名的后面直接加上built-in.o或lib.a,表示要连接进内核的文件,如下:




第604行中,vmlinux-all表示所有构成内核映像文件vmlinux的目标文件。把602和603代入604,可知目标文件顺序为:head-y、init-y、core-y、libs-y、drivers-y、net-y,即:


因此编译器就根据这个内容把内核映像文件vmlinux编译出来了。


。。。

顶层Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成内核映像文件vmlinux。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【ql君】qlexcel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值