uboot 配置 编译 连接全过程.docx

上传人:b****5 文档编号:7709931 上传时间:2023-01-25 格式:DOCX 页数:16 大小:293.79KB
下载 相关 举报
uboot 配置 编译 连接全过程.docx_第1页
第1页 / 共16页
uboot 配置 编译 连接全过程.docx_第2页
第2页 / 共16页
uboot 配置 编译 连接全过程.docx_第3页
第3页 / 共16页
uboot 配置 编译 连接全过程.docx_第4页
第4页 / 共16页
uboot 配置 编译 连接全过程.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

uboot 配置 编译 连接全过程.docx

《uboot 配置 编译 连接全过程.docx》由会员分享,可在线阅读,更多相关《uboot 配置 编译 连接全过程.docx(16页珍藏版)》请在冰豆网上搜索。

uboot 配置 编译 连接全过程.docx

uboot配置编译连接全过程

uboot配置编译连接全过程

分类:

Uboot2011-11-1420:

48415人阅读评论

(1)收藏举报

 

 根据README中PortingGuide的指示精神,我们要在新板子上移植UBoot,最快速的办法就是查看当前UBoot代码中是否有对相似于待移植板子的其他板子的支持(这应该又是一个可考虑成为习惯甚至本能的做法。

也即拿到不熟悉的软件包后,看看里面有没有自己熟悉的、或者和自己目前要做的东西很相似的部分,从这个部分入手往往能很快的解决问题)。

很幸运,我们在里面找到了三星公司所生产的SMDK2410参考板,这是三星公司早先为推销其生产的ARM9芯片-S3C2410所推出的一块PCB参考设计板(推出时随板子附加了很多的软硬件资料)。

知道这个后,我们很高兴,因为我们知道我们板子上的CPU——S3C2440正是S3C2410的升级版。

所以,在真正动手移植之前,分析一下新版本UBoot中如何支持SMDK2410的,自然成为接下来要做的事情。

UBoot本身是用GNU工具链开发的,那这就意味着其代码包里面必然会有很多的Makefile文件,因为GNUMake正是用来管理软件项目编译的GNU工具。

而且,正如我们前面说的,UBoot能支持如此多的CPU体系结构和操作系统,那它就必定会有很多的配置选项用于配置。

所以分析支持SMDK2410参考板的具体代码之前,我们必须先弄懂UBoot的配置编译过程。

我们只有对此了然于胸了,才能比较顺利的完成移植。

所幸的是,不像Linux内核代码,UBoot的代码量并不多,分析起来并不痛苦。

作为UBoot学习移植系列的第一篇文章,我在这里就以SMDK2410板子的支持作为例子,分析新版本UBoot(2010.06)的配置编译过程。

作为前提,你应该知道一些GNUMake以及一些BashShellScript的知识。

从UBOOT用户的角度来讲,其编译配置过程倒是非常的简单,只需要在命令行中切换到UBoot目录下输入两个命令:

[csicong@juliantecu-boot-2010.06]$makeARCH=armCROSS_COMPILE=arm-linux-smdk2410_config

[csicong@juliantecu-boot-2010.06]$makeARCH=armCROSS_COMPILE=arm-linux-

第一个命令完成UBootforsmdk2410参考板的配置,第二个命令则真正编译出所需要的UBoot二进制映像文件,编译出来之后我们需要将其下载到FLASH中。

在这两个命令中,参数ARCH表示我们要给具有何种体系结构的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=)armarm920tsmdk2410samsungs3c24x0

根据Makefile规则的定义,GNUMake在处理这条规则的时候,先判断其依赖——也就是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的处理,GNUMake回到对smdk2410_config的处理。

它接下来执行命令:

@$(MKCONFIG)$(@:

_config=)armarm920tsmdk2410samsungs3c24x0

在这条命令中,$(MKCONFIG)指代的就是UBoot根目录下的mkconfig脚本,因为你可以在同一Makefile中找到该变量的定义:

MKCONFIG:

=$(SRCTREE)/mkconfig

exportMKCONFIG

其中$(SRCTREE)指代的就是UBoot根目录。

另外在上面的命令中,$(@:

_config=)的部分实际上是处理自动变量$@,也就是第一次make的目标smdk2410_config,这里将其中"_config"的部分用空来代替。

去掉"_config"的部分后,剩余的smdk2410也就是三星参考板的名称。

所以最后上面的命令也就可直接写作:

./mkconfigsmdk2410armarm920tsmdk2410samsungs3c24x0

很清楚,执行mkconfig脚本,并传之以所在的目录名称,sansung是产商名称,s3c24x0是对应的SOC芯片名称。

有人对arm920和s3c24x0两者所指东西混淆不清,我自己在平时为方便起见也经常混用这两个词,有时候也将它们统称为CPU。

但实际上,更精确的说法认为arm920t是arm9类型的CPU核,而s3c2410则是用该核搭配另外一些外设做在一块芯片内形成的SOC芯片。

由于三星本身出了很多使用arm920tCPU核的芯片,如s3c2400、s3c2410以及s3c2440,所以在UBoot代码中,用s3c24x0来统称这一类SOC芯片。

mkconfig脚本是bash脚本。

对应于smdk2410参考板,其主要做三件事情:

1,在include目录下制作一些软连接,参见代码:

#

#Createlinktoarchitecturespecificheaders

#

if["$SRCTREE"!

="$OBJTREE"];then

mkdir-p${OBJTREE}/include

mkdir-p${OBJTREE}/include2

cd${OBJTREE}/include2

rm-fasm

ln-s${SRCTREE}/arch/$2/include/asmasm

LNPREFIX=${SRCTREE}/arch/$2/include/asm/

cd../include

rm-fasm

ln-s${SRCTREE}/arch/$2/include/asmasm

else

cd./include

rm-fasm

ln-s../arch/$2/include/asmasm

fi

 

rm-fasm/arch

 

if[-z"$6"-o"$6"="NULL"];then

ln-s${LNPREFIX}arch-$3asm/arch

else

ln-s${LNPREFIX}arch-$6asm/arch

fi

 

if["$2"="arm"];then

rm-fasm/proc

ln-s${LNPREFIX}proc-armvasm/proc

fi

由于我们编译UBoot时,通常都是在UBoot原有目录下编译的,并且针对smdk2410参板,"$2"="arm","$6"="s3c24x0",所以,以上代码的效果等同于我们用下面这些命令来手工创建软连接。

[csicong@juliantecinclude]$ln-s../arch/arm/include/asm./asm

[csicong@juliantecinclude]$ln-sarch-s3c24x0./asm/arch

[csicong@juliantecinclude]$ln-sproc-armv./asm/proc

2,在include目录下制作顶层Makefile要包含的文件include/config.mk,参见代码:

#

#CreateincludefileforMake

#

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,参见代码:

#AssignboarddirectorytoBOARDIRvariable

if[-z"$5"-o"$5"="NULL"];then

BOARDDIR=$4

else

BOARDDIR=$5/$4

fi

 

#

#Createboardspecificheaderfile

#

if["$APPEND"="yes"]#Appendtoexistingconfigfile

then

echo>>config.h

else

>config.h#Createnewconfigfile

fi

echo"/*Automaticallygenerated-donotedit*/">>config.h

 

foriin${TARGETS};do

echo"#defineCONFIG_MK_${i}1">>config.h;

done

 

cat<>config.h

#defineCONFIG_BOARDDIRboard/$BOARDDIR

#include

#include

#include

EOF

需要说明的是,上面一行">config.h"的作用是创建一个空文件。

有的同志可能不太知道,你可以在shell提示符下试验一下,其效果就和用touch命令一样。

这段代码会创建文件include/config.h,其内容如下:

/*Automaticallygenerated-donotedit*/

#defineCONFIG_BOARDDIRboard/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-outtools,$(SUBDIRS))$(TIMESTAMP_FILE)$(VERSION_FILE)gdbtools\

updaterenvdependdeptagsctagsetagscscope$(obj)System.map:

@echo"Systemnotconfigured-seeREADME">&2

@exit1

 

tools:

$(MAKE)-Ctools

tools-all:

$(MAKE)-CtoolsHOST_TOOLS_ALL=y

endif#config.mk

...

...//Bé?

¨å?

?

...

这个判断结构,其实就是看是否存在文件include/config.mk,如果存在的,则说明第一步的配置过程已经完成,因为这个文件正式配置过程中产生的。

所以此时GNUMake就会处理上面代码中的A部分,否则就会处理else后面、endif前面的部分。

从这里我们可以看出,如果不对UBoot进行配置,而直接去编译,那么它会给出一个警告,并要求我们去看README。

上面中的B部分就是UBoot中对各种所支持板子的规则定义,其中包括了我们前面提到过的对应于smdk2410_config的规则。

上面代码中的A部分是整个顶层Makefile的精华所在,其中包含了生成UBoot二进制映像的大部分规则定义,也是我们关注的重点。

好了,知道这样一个框架后,我们再回头来看看第二个命令的编译过程。

在开头提到的第二个命令中,我们并没有给make指定一个目标,所以按照GNUMake的规定,它将去着手处理默认规则,也即出现在顶层Makefile第一个规则all,如下:

#AlwaysappendALLsothatarchconfig.mk'scanaddcustomones

ALL+=$(obj)u-boot.srec$(obj)u-boot.bin$(obj)System.map$(U_BOOT_NAND)$(U_BOOT_ONENAND)

 

all:

$(ALL)

这条规则里面并没有命令,所以GNUMake在处理的时候,会依次去处理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)-Osrec$<$@

这其实是二进制代码的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)\

-Mapu-boot.map-ou-boot

$(obj)u-boot:

depend$(SUBDIRS)$(OBJS)$(LIBBOARD)$(LIBS)$(LDSCRIPT)$(obj)u-boot.lds

$(GEN_UBOOT)

ifeq($(CONFIG_KALLSYMS),y)

smap=`$(callSYSTEM_MAP,u-boot)|\

awk'$$2~/[tTwW]/{printf$$1$$3"\"}'`;\

$(CC)$(CFLAGS)-DSYSTEM_MAP="\"$${smap}\""\

-ccommon/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可得出规则如下:

#Explicitlymake_dependinsubdirscontainingmultipletargetstoprevent

#parallelsub-makescreating.dependfilessimultaneously.

dependdep:

$(TIMESTAMP_FILE)$(VERSION_FILE)$(obj)include/autoconf.mk

fordirin$(SUBDIRS)$(CPUDIR)$(dir$(LDSCRIPT));do\

$(MAKE)-C$$dir_depend;done

该规则先会处理三个依赖,$(TIMESTAMP_FILE)、$(VERSION_FILE)以及$(obj)include/autoconf.mk。

前两个分别生成UBoot本次编译的时间戳头文件和版本头文件。

而后者则由一个稍微复杂一点的规则处理,如下所示:

#

#Auto-generatetheautoconf.mkfile(whichisincludedbyallmakefiles)

#

#Thistargetactuallygenerates2files;autoconf.mkandautoconf.mk.dep.

#thedepfileisonlyincludeinthistoplevelmakefiletodeterminewhen

#toregeneratetheautoconf.mkfile.

$(obj)include/autoconf.mk.dep:

$(obj)include/config.hinclude/common.h

@$(XECHO)Generating$@;\

set-e;\

:

Generatethedependancies;\

$(CC)-xc-DDO_DEPS_ONLY-M$(HOSTCFLAGS)$(CPPFLAGS)\

-MQ$(obj)include/autoconf.mkinclude/common.h>$@

 

$(obj)include/autoconf.mk:

$(obj)include/config.h

@$(XECHO)Generating$@;\

set-e;\

:

Extracttheconfigmacros;\

$(CPP)$(CFLAGS)-DDO_DEPS_ONLY-dMinclude/common.h|\

sed-n-ftools/scripts/define2mk.sed>$@.tmp&&\

mv$@.tmp$@

处理autoconf.mk的规则看起来有点繁,但实际上它是以tools/scripts/define2mk.sed作为sed脚本来调用sed程序,其功能是将C语言中定义的宏配置转换成Makefile能理解的变量定义形式。

就smdk2410参考板来说我们可以举个例子:

在include/configs/smdk2410.h文件中有宏CONFIG_S3C2410的定义:

#defineCONFIG_S3C24101/*specificallyaSAMSUNGS3C2410SoC*/

那么这里的这个命令就会将其转换成如下的形式写到include/autoconfi.mk文件中去。

CONFIG_S3C2410=y

最终出来的include/autoconf.mk文件中都是类似的变量定义。

从下面的代码中可以看出这个文件将会被顶层M

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 研究生入学考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1