基于u-boot2011.06源码,开发板为友善之臂的Smart210:
在编译u-boot之前都得执行# make $Boardname_config ,我这里执行的是# make samrt210_config 要知道原因还得分析顶层makefile
<TOPDIR Makefile>
由上代码可知,在执行# make smart210_config时,先会执行unconfig目标,注意不指定输出目标时,obj,src变量均为空,unconfig下面的命令清理上一次执行make %_config时生成的头文件和makefile的包含文件。
在执行unconfig之后就是
@$(MKCONFIG) -A $(@:_config=)
sinclude $(obj).boards.depend
$(obj).boards.depend:boards.cfg
查找得知 #MKCONFIG:= $(SRCTREE)/mkconfig,在这里我们添加了boards.cfg 文件,其中boards.cfg 文件就有我们添加的
# Target ARCH CPU Board name Vendor SoC Options
smart210 arm armv7 smart210 samsung s5pc1xx
总结出mkconfig的作用就是有三个:
1>在include文件夹下建立相应的文件(夹)软连接,
#如果是ARM体系将执行以下操作
#ln -s asm-arm asm
#ln -s arch-s3c24x0 asm-arm/arch
#ln -s proc-armv asm-arm/proc
<TOPDIR mkconfig>
2>生成Makefile包含文件include/config.mk,内容很简单,定义了五个变量
ARCH = arm
CPU = armv7
BOARD = smart210
VENDOR = samsung
SOC = s5pc1xx<TOPDIR mkconfig>
3>生成include/config.h头文件,
/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/smart210
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/smart210.h>
#include <asm/config.h>
<TOPDIR mkconfig>
ok,mkconfig脚本文件的执行至此结束,我们所需的参数也已经传输进去了,现在可以从头分析Makefile的源码了
<TOPDIR Makefile>
u-boot顶层的Makefile已经注明了version了,我们这里移植的是u-boot2011.06版本
<TOPDIR Makefile>
注释已注明
顶层Makefile需要囊括整个工程文件的编译,所有难免要从外面引入变量或是参数,就像我们刚输入的五个参数,如果Makefile需要使用这几个参数,就需要将/include/config.mk文件包含进来,Makefile也可以像C文件那样使用include或是sinclude来包含其他外部文件 。
<TOPDIR Makefile>
添加u-boot的连接文件u-boot.lds,这个文件也是决定u-boot的执行入口和
定义了连接时各个目标文件是如何组织的:
<TOPDIR Makefile>
从这段代码可以看出,
LDSCRIPT是个很关键的变量,通过查找我们可以看到在arch/arm/config.mk中有这样的一个定义
<arch/arm/config.mk>
前面我们说过Makefile要使用外面文件的变量需要包含变量所在文件,我们这里调用
arch/arm/config.mk中得LDSCRIPT,那有没有包含呢?当然是有,在前面包含那部分代码中的最后一行可以看到include $(TOPDIR)/config.mk,而在顶层的config.mk中我们可以看到
<顶层config.mk>
其中就一段sinclude $(TOPDIR)/arch/$(ARCH)/config.mk,从我们传入的参数来看ARCH=arm,所以我们可以得出,include/config.mk是包含了arch/arm/config.mk
回到关键变量LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds ,在上面这段顶层config.mk中有定义CPUDIR变量,结合我们传入参数可知CPUDIR=arch/arm/cpu/armv7,所以LDSCRIPT :=arch/arm/cpu/armv7/u-boot.lds ,这就是我们所需要的链接文件,在这个文件就说明了u-boot的入口以及定义了连接时各个目标文件是如何组织的。
返回顶层Makefile继续分析
<TOPDIR Makefile>
U-boot需要的目标文件, 顺序很重要,start.o必须放第一位。
接下来就是添加需要的库文件了
<TOPDIR Makefile>
后面还有什么添加GCC库等一系列添加,就不一一贴出了
接下就是生产各种镜像了,首先贴出我的终极目标
<TOPDIR Makefile>
以下是各种镜像
<TOPDIR Makefile>
这只是部分镜像,从上面代码不难看出,各种镜像的生产都不离开彼此的依赖,而最低层的依赖文件就是u-boot ELF文件,所以我们就分析下关键的u-boot ELF文件镜像的生成
<TOPDIR Makefile>
@依赖目标depend :生成各个子目录的.depend文件,.depend列出每个目标文件的依赖文件。生成方法,调用每个子目录的make _depend。
<TOPDIR Makefile>
@依赖目标version:生成版本信息到版本文件VERSION_FILE中。
<TOPDIR Makefile>
@伪目标SUBDIRS: 执行tools, examples/standalone, examples/api 等子目录下面的make文件<TOPDIR Makefile>
@其他依赖目标
<TOPDIR Makefile>
@执行连接命令:
<TOPDIR Makefile>
其实就是把start.o和各个子目录makefile生成的库文件按照LDFLAGS连接在一起,生成ELF文件u-boot 和连接时内存分配图文件u-boot.map。
概括起来,工程的编译流程也就是通过执行执行一个make *_config传入ARCH,CPU,BOARD,SOC参数,mkconfig根据参数将include头文件夹相应的头文件夹连接好,生成config.h。然后执行make分别调用各子目录的makefile 生成所有的obj文件和obj库文件*.a. 最后连接所有目标文件,生成镜像。不同格式的镜像都是调用相应工具由elf镜像直接或者间接生成的。
至此u-boot的Makefile就分析结束了,这里只对顶层的makefile进行了分析,这也是对整个u-boot的一个结构分析,本人新手,这是根据自己的理解和网上各位大神的分析而得出的一个工作记录帖,不喜勿喷 |