首页 uboot配置编译连接全过程

uboot配置编译连接全过程

举报
开通vip

uboot配置编译连接全过程uboot配置编译连接全过程 uboot 配置 编译 连接全过程 分类: Uboot 2011-11-14 20:48 415人阅读 评论(1) 收藏 举报 根据README中 Porting Guide 的指示精神,我们要在新板子上移植UBoot,最快速的办法就是查看当前UBoot代码中是否有对相似于待移植板子的其他板子的支持(这应该又是一个可考虑成为习惯甚至本能的做法。也即拿到不熟悉的软件包后,看看里面有没有自己熟悉的、或者和自己目前要做的东西很相似的部分,从这个部分入手往往能很快的解决问题)。很幸运,我...

uboot配置编译连接全过程
uboot配置编译连接全过程 uboot 配置 编译 连接全过程 分类: Uboot 2011-11-14 20:48 415人阅读 评论(1) 收藏 举报 根据README中 Porting Guide 的指示精神,我们要在新板子上移植UBoot,最快速的办法就是查看当前UBoot代码中是否有对相似于待移植板子的其他板子的支持(这应该又是一个可考虑成为习惯甚至本能的做法。也即拿到不熟悉的软件包后,看看里面有没有自己熟悉的、或者和自己目前要做的东西很相似的部分,从这个部分入手往往能很快的解决问题)。很幸运,我们在里面找到了三星公司所生产的SMDK2410参考板,这是三星公司早先为推销其生产的ARM9芯片-S3C2410所推出的一块PCB参考 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 板(推出时随板子附加了很多的软硬件资料)。知道这个后,我们很高兴,因为我们知道我们板子上的CPU——S3C2440正是S3C2410的升级版。所以,在真正动手移植之前,分析一下新版本UBoot中如何支持SMDK2410的,自然成为接下来要做的事情。 UBoot本身是用GNU工具链开发的,那这就意味着其代码包里面必然会有很多的Makefile文件,因为GNU Make正是用来管理软件项目编译的GNU工具。而且,正如我们前面说的,UBoot能支持如此多的CPU体系结构和操作系统,那它就必定会有很多的配置选项用于配置。所以分析支 持SMDK2410参考板的具体代码之前,我们必须先弄懂UBoot的配置编译过程。我们只有对此‎‎了然于胸了,才能比较顺利的完成移植。所幸的是,不像Linux内核代码,UBoot的代码量并不多,分析起来并不痛苦。 作为UBoot学习移植系列的第一篇文章,我在这里就以SMDK2410板子的支持作为例子,分析新版本 UBoot(2010.06)的配置编译过程。作为前提,你应该知道一些GNU Make以及一些Bash Shell Script的知识。 从UBOOT用户的角度来讲,其编译配置过程倒是非常的简单,只需要在命令行中切换到UBoot 目录 工贸企业有限空间作业目录特种设备作业人员作业种类与目录特种设备作业人员目录1类医疗器械目录高值医用耗材参考目录 下输入两个命 令:[csicong@juliantec u-boot-2010.06]$ make ARCH=arm CROSS_COMPILE=arm-linux- smdk2410_config [csicong@juliantec u-boot-2010.06]$ make ARCH=arm CROSS_COMPILE=arm-linux- 第一个命令完成UBoot for smdk2410参考板的配置,第二个命令则真正编译出所需要的 UBoot 二进制映像文件,编译出来之后我们需要将其下载到FLASH中。在这两个命令中,参数ARCH 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示我们要给具有何种体系结构的CPU编译UBoot,因为不管SMDK2410参考板上的 CPU——S3C2410,还是我手头板子上的CPU,皆为ARM9芯片,所以这里显然应该为arm;CROSS_COMPILE为交叉编译工具链各工具的名称前缀。我们需要用 到arm-linux-gcc作为编译器、arm-linux-ld为链接器。。。所以这里取值为 arm-linux- 。 在第一个命令中,我们以 smdk2410_config 作为本次 make 的目标。查找UBoot项目顶层 Makefile 得到关于此目标的规则如下 : smdk2410_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x 0 根据 Makefile 规则的定义,GNU Make在处理这条规则的时候,先判断其依赖——也就是 unconfig 是否需要更新。而我们在同一Makefile中找到 unconfig 的规则为(482行): unconfig: @rm -f $(obj)include/config.h $(obj)include/config.mk\ $(obj)board/*/config.tmp$(obj)board/*/*/config.tmp \ $(obj)include/autoconf.mk$(obj)include/autoconf.mk.dep 由于目录下没有一个叫 unconfig 的文件存在,所以和 unconfig 相关的这条规则总是得到处理,也就是其中的 rm 命令总是得到执行,该命令的目的是删除一些配置编译过程中产生的文件。在这些文件中,与本文讨论密切相关的是前 面两个,以及后面两个。前面两个是用第一条命令来配置UBoot的过程中产生的,后面则是用第二条命令来编译UBoot的过程中产生的。这条规则先把‎‎他们全部删除。注意rm命令前面的@符号是取消该命令执行时的回显。 执行完对依赖——unconfig的处理,GNU Make 回到对 smdk2410_config 的处理。它接下来执行命令: @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x 0 在这条命令中,$(MKCONFIG) 指代的就是 UBoot 根目录下的 mkconfig 脚本,因为你可以在同一Makefile中找到该变量的定义: MKCONFIG := $(SRCTREE)/mkconfig export MKCONF IG 其中 $(SRCTREE) 指代的就是UBoot 根目录。另外在上面的命令中,$(@:_config=) 的部分实际上是处理自动变量 $@,也就是第一次 make 的目标 smdk2410_config,这里将其中"_config"的部分用空来代替。去掉"_config"的部分后,剩余的 smdk2410 也就是三星参考板的名称。所以最后上面的命令也就可直接写作: ./mkconfig smdk2410 arm arm920t smdk2410 samsung s3c24x0 很清楚,执行 mkconfig 脚本,并传之以所在的目录名称,sansung 是产商名称,s3c24x0是对应的SOC芯片名称。有人对arm920和s3c24x0两者所指东西混淆不清,我自己在平时为方便起见也经常混用这两个词,有时候也将它们统称为CPU。但实际上,更精确的说法认为arm920t是arm9类型的CPU核,而s3c2410则是用该核搭配另外一些外设做在一块芯片内形成的SOC芯片。由于三星本身出了很多使用arm920tCPU核的芯片,如s3c2400、s3c2410以及s3c2440,所以在UBoot代码中,用s3c24x0来统称这一类SOC芯片。 mkconfig 脚本是 bash 脚本。对应于smdk2410参考板,其主要做三件事情: 1,在include目录下制作一些软连接,参见代码: # # Create link to architecture specific headers # if [ "$SRCTREE" != "$OBJTREE" ] ; then mkdir -p ${OBJTREE}/include mkdir -p ${OBJTREE}/include2 cd ${OBJTREE}/include2 rm -f asm ln -s ${SRCTREE}/arch/$2/include/asm asm LNPREFIX=${SRCTREE}/arch/$2/include/asm/ cd ../include rm -f asm ln -s ${SRCTREE}/arch/$2/include/asm asm else cd ./include rm -f asm ln -s ../arch/$2/include/asm asm fi rm -f asm/arch if [ -z "$6" -o "$6" = "NULL" ] ; then ln -s ${LNPREFIX}arch-$3 asm/arch else ln -s ${LNPREFIX}arch-$6 asm/arch fi if [ "$2" = "arm" ] ; then rm -f asm/proc ln -s ${LNPREFIX}proc-armv asm/proc fi 由于我们编译UBoot时,通常都是在UBoot原有目录下编译的,并且针对smdk2410参板,"$2"="arm","$6"="s3c24x0",所以,以上代码的效果等同于我们用下面这些命令来手工创建软连接 。 [csicong@juliantec include]$ ln -s ../arch/arm/include/asm ./asm [csicong@juliantec include]$ ln -s arch-s3c24x0 ./asm/arch [csicong@juliantec include]$ ln -s proc-armv ./asm/proc 2, 在include目录下制作顶层Makefile要包含的文件 include/config.mk,参见代码: # # Create include file for Make # echo "ARCH = $2" > config.mk echo "CPU = $3" >> config.mk echo "BOARD = $4" >> config.mk [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk 很明显,制作出来的文件 include/config.mk,其内容非常简单,只包括 ARCH、CPU、BOARD、VENDOR、SOC等变量的定义。后面我们会知道,这个文件虽然简单,但是却决定了顶层 Makefile的一大部分逻辑框架。 3, 在include目录下制作产生特定于smdk2410参考板的头文件 include/config.h,参见代码: # Assign board directory to BOARDIR variable if [ -z "$5" -o "$5" = "NULL" ] ; then BOARDDIR=$4 else BOARDDIR=$5/$4 fi # # Create board specific header file # if [ "$APPEND" = "yes" ] # Append to existing config file then echo >> config.h else > config.h # Create new config file fi echo "/* Automatically generated - do not edit */" >>config.h for i in ${TARGETS} ; do echo "#define CONFIG_MK_${i} 1" >>config.h ; done cat << EOF >> config.h #define CONFIG_BOARDDIR board/$BOARDDIR #include #include #include EOF 需要说明的是,上面一行 "> config.h" 的作用是创建一个空文件。有的同志可能不太知道,你可以在shell提示符下试验一下,其效果就和用 touch 命令一样。这段代码会创建文件include/config.h,其内容如下: /* Automatically generated - do not edit */ #define CONFIG_BOARDDIR board/samsung/smdk2410 #include #include #include 至此,针对smdk2410参考板来配置新版本的UBoot代码完成了,接下来,我们能使用上面的第二个命令来编译可以该参考板上引导Linux内核的UBoot了。 在讨论编译UBoot的第二个命令之前,你需要稍微看一下 UBoot 顶层Makefile的内容,其实里面最重要的部分就是一个条件判断结构,抽出代码如下 : ... ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk)) ...//A else # !config.mk all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \ $(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \ $(filter-out tools,$(SUBDIRS)) $(TIMESTAMP_FILE) $(VERSION_FILE) gdbtools \ updater env depend dep tags ctags etags cscope $(obj)System.map: @echo "System not configured - see README" >&2 @ exit 1 tools: $(MAKE) -C tools tools-all: $(MAKE) -C tools HOST_TOOLS_ALL=y endif # config.mk ... ...//B é??å?? ... 这个判断结构,其实就是看是否存在文件 include/config.mk,如果存在的,则说明第一步的配置过程已经完成,因为这个文件正式配置过程中产生的。所以此时GNU Make就会处理上面代码中的 A 部分,否则就会处理else后面、endif前面的部分。从这里我们可以看出,如果不对UBoot进行配置,而直接去编译,那么它会给出一个警告,并要求我们去看README。上面中的 B 部分就是UBoot中对各种所支持板子的规则定义,其中包括了我们前面提到过的对应于smdk2410_config 的规则。 上面代码中的 A 部分是整个顶层 Makefile 的精华所在,其中包含了生成UBoot二进制映像的大部分规则定义,也是我 们关注的重点。好了,知道这样一个框架后,我们再回头来看看第二个命令的编译过程 。 在开头提到的第二个命令中,我们并没有给 make 指定一个目标,所以按照 GNU Make 的 规定 关于下班后关闭电源的规定党章中关于入党时间的规定公务员考核规定下载规定办法文件下载宁波关于闷顶的规定 ,它将去着手处理默认规则,也即出现在顶层Makefile第一个规则 all ,如下: # Always append ALL so that arch config.mk's can add custom ones ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) all: $(ALL) 这条规则里面并没有命令,所以GNU Make在处理的时候,会依次去处理ALL中的这五个目标。而针对smdk2410参考板,没有定义CONFIG_NAND_U_BOOT和 CONFIG_ONENAND_U_BOOT,所以依据下面的规则,后面两个目标:$(U_BOOT_NAND) $(U_BOOT_ONENAND)将为空。 ifeq ($(CONFIG_NAND_U_BOOT),y) NAND_SPL = nand_spl U_BOOT_NAND = $(obj)u-boot-nand.bin endif ifeq ($(CONFIG_ONENAND_U_BOOT),y) ONENAND_IPL = onenand_ipl U_BOOT_ONENAND = $(obj)u-boot-onenand.bin ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin endif 所以对UBoot的这次编译过程,将会在UBoot顶层目录中生成三个文件,u-boot.srec、u-boot.bin 以及 System.map。其中u-boot.bin正式我们所需要的二进制映像文件,我们可以把它直接下载到板子的FLASH上用于引导Linux操作系统。 对于第一个文件 u-boot.srec,其对应的规则为: $(obj)u-boot.srec: $(obj)u-boot $(OBJCOPY) -O srec $< $@ 这其实是二进制代码的SRecord格式表示。这种格式最先用在摩托罗拉6800处理器上,专门用于处理二进制数据在不同设备之间的传输上。但是就用GNU工具进行smdk2410参考板的开发来说,是用不到的。我们只需要最原始的二进制数据映像u-boot.bin即可,里面包含纯粹的二进制指令和数据,并没有用过任何格式包装过 。 不过先不管到底u-boot.srec有没有用,根据上面处理u-boot.srec的规则定义,在处理 u-boot.srec 之前,先 要处理 u-boot(它是一个ELF格式可执行文件) ,查找对应的规则定义如下: GEN_UBOOT = \ UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \ sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort| uniq`;\ cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot.map -o u-boot $(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds $(GEN_UBOOT) ifeq ($(CONFIG_KALLSYMS),y) smap=`$(call SYSTEM_MAP,u-boot) | \ awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\"}'` ; \ $(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \ -c common/system_map.c -o $(obj)common/system_map.o $(GEN_UBOOT) $(obj)common/system_map.o endif 由上面的规则可知,目标 u-boot 的依赖有很多个,为:depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds。 $(GEN_UBOOT) 是该规则命令集的第一个部分。 而对于SMDK2410参考板来说,CONFIG_KALLSYMS并未定义,所以该规则的命令实际上只有实际上只有变量$(GEN_UBOOT)所指代的部分。 此规则处理的第一个目标为 depend,查找同一 Makefile 可得出规则如下: # Explicitly make _depend in subdirs containing multiple targets to prevent # parallel sub-makes creating .depend files simultaneously. depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk for dir in $(SUBDIRS) $(CPUDIR) $(dir $(LDSCRIPT)) ; do \ $(MAKE) -C $$dir _depend ; done 该规则先会处理三个依赖,$(TIMESTAMP_FILE)、$(VERSION_FILE)以及$(obj)include/autoconf.mk。前两个分别生成UBoot本次编译的时间戳头文件和版本头文件。而后者则由一个稍微复杂一点的规则处理,如下所示: # # Auto-generate the autoconf.mk file (which is included by all makefiles) # # This target actually generates 2 files; autoconf.mk and autoconf.mk.dep. # the dep file is only include in this top level makefile to determine when # to regenerate the autoconf.mk file. $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h @$(XECHO) Generating $@ ; \ set -e ; \ : Generate the dependancies ; \ $(CC) -x c -DDO_DEPS_ONLY -M $(HOSTCFLAGS) $(CPPFLAGS) \ -MQ $(obj)include/autoconf.mk include/common.h > $@ $(obj)include/autoconf.mk: $(obj)include/config.h @$(XECHO) Generating $@ ; \ set -e ; \ : Extract the config macros ; \ $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \ sed -n -f tools/scripts/define2mk.sed > $@.tmp && \ mv $@.tmp $@ 处理 autoconf.mk 的规则看起来有点繁,但实际上它是以tools/scripts/define2mk.sed作为sed脚本来调用sed程序,其功能是将C语言中定义的宏配置转换成Makefile能理解的变量定义形式。就smdk2410参考板来说我们可以举个例子:在 include/configs/smdk2410.h 文件中有宏 CONFIG_S3C2410 的定义: #define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */ 那么这里的这个命令就会将其转换成如下的形式写到 include/autoconfi.mk 文件中去。 CONFIG_S3C2410=y 最终出来的 include/autoconf.mk 文件中都是类似的变量定义。从下面的代码中可以看出这个文件将会被顶层 Makefile 所包含进去: # Include autoconf.mk before config.mk so that the config options are available # to all top level build files. We need the dummy all: target to prevent the # dependency target in autoconf.mk.dep from being the default. all: sinclude $(obj)include/autoconf.mk.dep sinclude $(obj)include/autoco nf.mk 那么,include/autoconf.mk.dep 又是做什么用的呢,实际上它内部定义了目标 include/autoconf.mk 的依赖有哪些。我们可以列出 autoconf.mk.dep的内容 如下:include/autoconf.mk: include/common.h \ /home/yihect/u-boot-2010.06/include/config.h \ /home/yihect/u-boot-2010.06/include/config_defaults.h \ /home/yihect/u-boot-2010.06/include/configs/smdk2410.h \ /home/yihect/u-boot-2010.06/include/config_cmd_default.h \ /home/yihect/u-boot-2010.06/include/asm/config.h \ /home/yihect/u-boot-2010.06/include/linux/bitops.h \ /home/yihect/u-boot-2010.06/include/asm/types.h \ /home/yihect/u-boot-2010.06/include/asm/bitops.h \ /home/yihect/u-boot-2010.06/include/asm/proc/system.h \ /home/yihect/u-boot-2010.06/include/linux/config.h \ /home/yihect/u-boot-2010.06/include/linux/types.h \ /home/yihect/u-boot-2010.06/include/linux/posix_types.h \ /home/yihect/u-boot-2010.06/include/linux/stddef.h \ /home/yihect/u-boot-2010.06/include/asm/posix_types.h \ /home/yihect/u-boot-2010.06/include/linux/string.h \ /home/yihect/u-boot-2010.06/include/asm/string.h \ /home/yihect/u-boot-2010.06/include/asm/ptrace.h \ /home/yihect/u-boot-2010.06/include/asm/proc/ptrace.h \ /home/yihect/eldk/usr/bin/../lib/gcc/arm-linux-gnue abi/4.2.2/include/stdarg.h \ /home/yihect/u-boot-2010.06/include/part.h \ /home/yihect/u-boot-2010.06/include/ide.h \ /home/yihect/u-boot-2010.06/include/flash.h \ /home/yihect/u-boot-2010.06/include/image.h \ /home/yihect/u-boot-2010.06/include/compiler.h \ /home/yihect/eldk/usr/bin/../lib/gcc/arm-linux-gnue abi/4.2.2/include/stddef.h \ /home/yihect/u-boot-2010.06/include/asm/byteorder.h \ /home/yihect/u-boot-2010.06/include/linux/byteorder/little_endian.h \ /home/yihect/u-boot-2010.06/include/linux/byteorder/swab.h \ /home/yihect/u-boot-2010.06/include/linux/byteorder/generic.h \ /home/yihect/u-boot-2010.06/include/lmb.h \ /home/yihect/u-boot-2010.06/include/asm/u-boot.h \ /home/yihect/u-boot-2010.06/include/command.h \ /home/yihect/u-boot-2010.06/include/asm/global_data.h \ /home/yihect/u-boot-2010.06/include/asm/mach-types.h \ /home/yihect/u-boot-2010.06/include/asm/setup.h \ /home/yihect/u-boot-2010.06/include/asm/u-boot-arm.h \ /home/yihect/u-boot-2010.06/include/net.h \ /home/yihect/u-boot-2010.06/include/u-boot/crc.h 这样一个文件就是由上面那条对应 autoconf.mk.dep 的规则所生成的。由上面可知,这样一个文件的内容也会被包含到UBoot 顶层 Makefile 中。讨论到这里,也许您觉得关于 autoconf 的这两条规则都没什么要说的了。但是还有一个问题:那就是 autoconf.mk 和 autoconf.mk.dep 是如何生成的,因为这两个文件都是被 sinclude 到顶层 Makefile 中去的,而在我们使用 Make 编译 UBoot 的时候此两个文件并不存在,所以按照 GNU Make的规范,它在全部读入顶层Makefile后,需要重新生成做 sinclude 时找不到的这两个文件。生成后它又会重新处理顶 层Makefile,并重新包含这两个文件。所以此处(depend规则)对$(obj)include/autoconf.mk处理时,它要做的只是检 查检查相关的依赖,决定是否需要重新生成 autoconf.mk 文件。 depend规则中,处理完所有依赖后,GNU Make 会循环进入一些目录去 make 一个特定的目标 _depend,我们这里不再详细深入考察这个部分。我觉得唯一需要您注意的是,对于smdk2410参考板来说,变量LDSCRIPT定义在文件 arch/arm/config.mk 中,如下示: LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds 这个变量定义了链接时需要使用到的链接脚本,其内容我们会在后续的文章中深入分析。另外如下面所示,我们也知道 arch/arm/config.mk 也是一个被间接 sinclude 到顶层 Makefile 中的文件,该文件的其他内容比较简单,请读者自行分析。 sinclude $(TOPDIR)/arch/$(ARCH)/config.mk # include architecture dependend rules 好了,回到我们对 u-boot 规则的处理上面来,下一个要处理的依赖是 $(SUBDIRS),我们可找到相关的规则如下 :$(SUBDIRS): depend $(MAKE) -C $@ all 从上面可以看出,它要依赖于 depend,这个我们前面已经处理过了,所以GNU Make要依次进入一系列的目录去 make 目标all。这里值得一说的是,它会进入到 tools 目 录下去编译一些工具,其中最重要的当数 mkimage 工具。作为留给读者的练习,请您预先去查找google,了解它的用途及用法。 接下来,GNU Make下一个要处理的依赖是 $(OBJS)。变量OBJS定义在下面: ################################################### ###################### # U-Boot objects....order is important (i.e. start must be first) OBJS = $(CPUDIR)/start.o ifeq ($(CPU),i386) OBJS += $(CPUDIR)/start16.o OBJS += $(CPUDIR)/resetvec.o endif ifeq ($(CPU),ppc4xx) OBJS += $(CPUDIR)/resetvec.o endif ifeq ($(CPU),mpc85xx) OBJS += $(CPUDIR)/resetvec.o endif OBJS := $(addprefix $(obj),$(OBJS)) 以 $(OBJS) 为目标的规则可找到如下: $(OBJS): depend $(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@)) 对于 smdk2410 参考板来说,变量 OBJS 只定义有一个对象文件。就是这样一个文件start.o,在后面链接形成 u-boot 时将被放在u-boot的最前面。后面会知道,这个文件里的程序将至关重要。因为系统上电后要执行的第一条指令将位于这个文件内。 下面要处理的依赖是 $(LIBBOARD),找到对应的变量定义以及规则如下: LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) $(LIBBOARD): depend $(LIBS) $(MAKE) -C $(dir $(subst $(obj),,$@)) 其中变量 BOARDDIR 定义在根目录的config.mk中,如下所示: ifdef VENDOR BOARDDIR = $(VENDOR)/$(BOARD) else BOARDDIR = $(BOARD) endif ifdef BOARD sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules endif 针对smdk2410参考板,BOARDDIR的值计算出来是:samsung/s3c24x0。为什么呢,因为根目录中的 config.mk 是被直接包含进顶层Makefile的,在此之前,顶层Makefile包含 include/config.mk 的。而通过前面的讨论,我们知道正是在这个文件定义了 ARCH/CPU/BOARD/VENDOR/SOC 等变量的定义,这是在配置过程中产生的。 讨论到这里,读者也许迷惑于 UBoot 中如此多的 *.mk 文件包含。干脆我们把它们列一下是形成下面的图片。其实比较运气的是,UBoot中的 Makefile 包含文件,都是以 .mk 结尾的,所以我们理起来,也比较方便。 顶层 Makefile 包含了根目录下的 config.mk,而根目录下的 config.mk 则包含了不同板子、不同CPU架构特定的 config.mk,它们都被安排在不同的目录下面。这里需要引起注意的是,对于smdk2410参考板,在目录 arch/arm/cpu/arm920t/s3c24x0 下面并不存在 config.mk,但是这里却将它 sinclude 进来。这种做法并不会引发 make 时的错误,因为其用的是 sinclude,而非 include。 另外,从 LIBBOARD 的处理规则上可以看出来, LIBBOARD 目标是依赖于 LIBS的,所以在处理 LIBBOARD 之前,GNU Make 会依次编译生成用到的不同种类的库。只有 LIBS 处理完成后,GNU Make才会动手去编译生成 LIBBOARD。 好,从 u-boot 对应规则上看,GNU Make 要处理的下一步要做的是处理 $(LIBS) 目标,但是正因为刚刚提到的 LIBBOARD 要依赖于 LIBS,所以实际上 LIBS 先于 LIBBOARD 而得到处理,其在 Makefile 中对应的变量定义及规则如下: LIBS = lib/libgeneric.a LIBS += lib/lzma/liblzma.a LIBS += lib/lzo/liblzo.a ...... LIBS := $(addprefix $(obj),$(LIBS)) .PHONY : $(LIBS) $(TIMESTAMP_FILE) $(VERSION_FILE) $(LIBS): depend $(SUBDIRS) $(MAKE) -C $(dir $(subst $(obj),,$@)) 它就要进入各个目录中去编译一个个的归档库文件,这没什么好说的。 接下来对u-boot规则要处理的依赖是 $(LDSCRIPT),变量 LDSCRIPT 被定义在文件:arch/arm/config.mk 中: LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds 而处理 $(LDSCRIPT) 的规则则被放在顶层Makefile 中: $(LDSCRIPT): depend $(MAKE) -C $(dir $@) $(notdir $@) 正如你所看到的,这条规则会使 GNU Make 进去到目录 $(SRCTREE)/$(CPUDIR)/ 中去做 make u-boot.lds 的动作。而针对 smdk2410 参考板来说,这个目录为 arch/arm/cpu/arm920t/,观察一下,此目录的 Makefile 中并无 u-boot.lds 的规则定义,所以这个规则针对 smdk2410 参考板来说将不会使 GNU Make 做任何动作。 好,接下来,处理 u-boot 目标的最后一个依赖是 $(obj)u-boot.lds,在顶层 Makefile 中查找出对应的规则定义如下: $(obj)u-boot.lds: $(LDSCRIPT) $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ 这条规则的意思就是要对 arch/arm/cpu/arm920t/ 目录下的 u-boot.lds 文件作预处理,并将结果保存为 UBoot 根目录下名叫 u-boot.lds 的文件中,其内容我们在以后的文章中再行分析。 好,GNU Make 处理完 u-boot 规则的所有依赖后,接下来要执行该规则对应的命令集来生成 u-boot 。首当其冲的是要执行 GEN_UBOOT 所指代的命令。查找出 GEN_UBOOT 变量的定义如下: GEN_UBOOT = \ UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \ sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort| uniq`;\ cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot.map -o u-boot 由上面的定义可知,这里的命令正是进入到 UBoot 根目录 中,并使用链接器将前面产生的 start.o、各种库链接起来, 构成一个 ELF 格式的可执行映像 u-boot,这可以从编译 UBoot 的输出结果的最后一部分中‎‎看出来(用省略号代替了 部分内容): UNDEF_SYM=`arm-linux-objdump -x board/samsung/smdk2410/libsmdk2410.a .....`; cd /home/yihect/u-boot-2010.06 && arm-linux-ld -Bstatic -T u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM arch/arm/cpu/arm920t/start.o --start-group lib/libgeneric.a ...... board/samsung/smdk2410/libsmdk2410.a --end-group /home/yihect/u-boot-2010.06/arch/arm/lib/eabi_compa t.o -L /home/yihect/eldk/usr/bin/../lib/gcc/arm-linux-gnue abi/4.2.2/soft-float -lgcc -Map u-boot.map -o u-boot arm-linux-objcopy -O srec u-boot u-boot.srec arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin 有了 u-boot 这个ELF映像后,从上面输出结‎‎果的最后两行可以看出来,GNU Make 将会用 arm-linux-objcopy 工具将 srec 格式映像文件转换出来;对于 u-boot.bin 也以类似的方式 用 objcopy 转出来,这个文件里面包含了纯粹的二进制指令和数据,没有使用任何的格式进行封装。这个正是smdk2410参考板所需要的,开发者会将这个文件下载到板子的FLASH里面来引导操作系统。 总结一下:对于要使用UBoot的用户来说,UBoot的配置编译时非常简单的,只需要两个命令的调用就好。但是正如你所见,其台面下的动作还是非常之多,要了解规模不算大也不算小的这样一个工程还是得花费一些时间的。当然,我们讲正是一份汗水、一份收获。等到你要动手移植UBoot的时候,就会懂得这份汗水的珍贵。另外,如果您想分析Linux内核代码的配置编译过程,不乏以UBoot工程代码作为开始和练习的机会。 分享到: , 上一篇:嵌入式系统Boot Loader启动全过程详解 , 下一篇:uboot 移植全过程---基于ARM9 2410
本文档为【uboot配置编译连接全过程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_321575
暂无简介~
格式:doc
大小:89KB
软件:Word
页数:0
分类:企业经营
上传时间:2017-09-19
浏览量:25