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

Arm Linux交叉编译和连接过程分析(2)

2013-11-04 22:38 429 查看

二、编译内核镜像过程

1、编译过程中涉及到到文件:

/Makefile
编译产生顶层vmlinux镜像文件

/scripts/Kbuild.includemake过程中到一些基本定义

/scripts/Makefile.lib编译内核时用到到函数库文件

/scripts/Makefile.build内核编译到相关命令文件

/arch/arm/Makefile这个是体系结构相关makefile文件

/arch/arm/Kconfig内核编译到配置文件

/arch/arm/boot/Makefile生成uImage,zImage,Image到编译文件

/arch/arm/boot/compressed/Makefile生成最终vmlinux到编译文件

/arch/arm/mach-sep4020/MakefileSEP4020系统结构的编译文件


2、编译过程解析;

2.1/include/linux/autoconfig.h的产生:

在顶层Makefile的487行有相应的编译命令,这个就是把我们顶层的.config文件转变成相应的系统的autoconfig.h文件,而在/include/linux/config.h中有这么一句:
#include<linux/autoconf.h>
以后在c文件中会包含这个/include/linux/config.h头文件的,也即包含了linux/autoconf.h文件



2.2、vmlinux的依赖关系

[align=left]2.2.1在/Makefile中的298行[/align]
[align=left]#Weneedsomegenericdefinitions[/align]
[align=left]include$(srctree)/scripts/Kbuild.include[/align]
[align=left]包含了scripts/Kbuild.include文件,在这里定义了大量的函数和变量,供顶层makefile和其他makefile文件使用。[/align]

2.2.2在顶层makefile文件的第175行,包含了arch/arm/Makefile。这个是体系结构相关makefile文件。它定义了体系结构相关的一些变量及规则。



[align=left][/align]
下面这个地方将/arch/arm/Makefile文件引入



2.2.3当执行”make”时,arch/arm/Makefile中的499行的规则将是make遇到的第一个规则:

all:vmlinux

exportKBUILD_IMAGE?=vmlinux(变量赋值)
2.2.4vmlinux目标的规则在顶层Makefile的第741行定义。

vmlinux:$(vmlinux-lds)$(vmlinux-init)$(vmlinux-main)$(kallsyms.o)FORCE
[align=left]$(callif_changed_rule,vmlinux__)[/align]
[align=left]$(Q)rm-f.old_version[/align]



2.2.5这里涉及到几个变量,先看看这几个变量的定义,前三个变量分别在顶层Makefile的605、606、608行定义。
[align=left][/align]



2.2.6其中head-y在arch/arm/Makefile中第72行定义,

head-y:=arch/arm/kernel/head.oarch/arm/kernel/init_task.o

2.2.7init-y在顶层makefile的462行定义



后又在第567行进行处理

init-y:=$(patsubst%/,%/built-in.o,$(init-y))

这里的$(patsubst%/,%/built-in.o,$(init-y))这个语句就是将init/下的所有c文件编译成目标文件build-in.o

所以变量init-y应为

init-y:=init/built-in.o

因此

vmlinux-init:=arch/arm/kernel/head$(MMUEXT).oarch/arm/kernel/init_task.oinit/built-in.o

同理,其他几个变量也可通过类似方法进行分析,这里不一一分析了。
2.5vmlinux-init这个变量的产生构建规则在顶层Makefile747行定义:

$(sort$(vmlinux-init)$(vmlinux-main))$(vmlinux-lds):$(vmlinux-dirs);

这里是一个空命令的规则。空命令行可以防止make在执行时试图为重建这个目标去查找隐含命令。其依赖为vmlinux-dirs,这个变量在顶层Makefile第561行定义:



[align=left][/align]
这个变量指定了一系列要进入的下层目录。他的规则在顶层Makefile第757行定义

$(vmlinux-dirs):preparescripts

$(Q)$(MAKE)$(build)=$@

这里的两个依赖就不分析了,主要看一下这个规则的命令,build和$@变量展开后如下

$(Q)$(MAKE)-f$(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build\

obj=$(vmlinux-dirs)

这里会再一次进入scripts/Makefile.build执行82行规则

__build:$(if$(KBUILD_BUILTIN),$(builtin-target)$(lib-target)$(extra-y))\

$(if$(KBUILD_MODULES),$(obj-m))\

$(subdir-ym)$(always)

@:

$(if$(KBUILD_BUILTIN),$(builtin-target))表示若KBUILD_BUILTIN定义了,则整个表达式为$(builtin-target)

因为KBUILD_BUILTIN在顶层Makefile195行中被初始化为1,所以这个规则的依赖有一个builtin-target变量。这个变量在scripts/Makefile.build的77行定义

ifneq($(strip$(obj-y)$(obj-m)$(obj-n)$(obj-)$(lib-target)),)
builtin-target:=$(obj)/built-in.o

endif
(strip用法:strip<选项>输入文件作用:从文件中删除符号和节)

变量obj就是vmlinux-dirs变量指定的目录,这在前面说到的。所以这里会构建$(vmlinux-dirs)/built-in.o目标,在scripts/Makefile.build文件的251行开始,有这个目标的规则及命令的定义



[align=left][/align]
scripts/Makefile.build在第15行开始包含了vmlinux-dirs变量指定目录中的Makefile文件,在这些makefile文件中会指定obj-y变量,它指定的都是一些*.o目标文件,

[align=left][/align]



这些*.o文件的生成方法由scripts/Makefile.build文件192行的模式规则指定

%.o:%.cFORCE

$(callcmd,force_checksrc)

$(callif_changed_rule,cc_o_c)



[align=left]这个就是我们看到的编译各个目录下.o目标文件的过程,这个中间在182行中:[/align]
[align=left]$(if$($(quiet)cmd_cc_o_c),echo'$(callescsq,$($(quiet)cmd_cc_o_c))';)\(其中的分号表示不显示命令执行)[/align]
[align=left]这个就会在屏幕上输出编译的信息:[/align]
CCnet/ipv4/devinet.o

通过上面这一系列的步骤,就编译链接出由变量vmlinux-init指定的目标,vmlinux-main变量指定的目标的构建与此类似。
[align=left][/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: