您的位置 首页 FPGA

uboot移植详解

参考:《嵌入式Linux应用开发完全手册》韦东山编著第15章移植U-boothttp://xgc94418297.blog.163.com/blog/static/112966040200952…

参阅:

嵌入式Linux运用开发彻底手册》 韦东山编著 第15章 移植 U-boot

http://xgc94418297.blog.163.com/blog/static/112966040200952971543686/

uboot是一段小程序,它在体系上电是开端履行,初始化硬件设备;准备好软件环境;最终调用操作体系内核。

这儿首要剖析移植进程。

U-boot中有几千个文件,要想了解关于某款开发板,运用哪些文件、哪个文件先履行、可履行文件占用内存的状况,最好的办法便是阅览它的Makefile文件。

要想运用哪款开发板就需首要履行“make _config”指令进行装备,然后履行“make all”就可生成三个文件,分别是:

U-Boot.bin:二进制可履行文件,可直接烧入ROM、NORFLASH

U-Boot.elf

U-Boot.srec:Motorola S-Record格局的可履行文件

U-Boot编译指令

关于TX2440开发板,编译U-Boot需求履行如下的指令:

$makeTX2440_config

$makeall

运用上面的指令编译U-Boot,编译生成的一切文件都保存在源代码目录中。为了坚持源代码目录的洁净,能够运用如下指令将编译生成的文件输出到一个外部目录,而不是在源代码目录中,下面的2种办法都将编译生成的文件输出到/tmp/build目录:

$exportBUILD_DIR=/tmp/build

$makeTX2440_config

$makeall

$makeO=/tmp/buildTX2440_config(留意是字母O,而不是数字0)

$makeall

makeTX2440_config指令履行进程

下面剖析指令“makeTX2440_config”履行进程,为了简化剖析进程这儿首要剖析将编译方针输出到源代码目录的状况。

TX2410_config:unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t TX2410 NULL s3c24x0

其间的依靠“unconfig”界说如下:

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

其间“@”的效果是履行该指令时不在shell显现。“obj”变量便是编译输出的目录,因而“unconfig”的效果便是铲除前次履行make*_config指令生成的装备文件(如include/config.h,include/config.mk等)。

$(MKCONFIG)在上面指定为“$(SRCTREE)/mkconfig”。$(@:_config=)为将传进来的一切参数中的_config替换为空(其间“@”指规矩的方针文件名,在这儿便是“TX2440_config”。$(text:patternA=patternB),这样的语法表明把text变量每一个元素中结束的patternA的文本替换为patternB,然后输出)。因而$(@:_config=)的效果便是将TX2440_config中的_config去掉,得到TX2440。

因而@$(MKCONFIG) $(@:_config=) arm arm920t TX2440 NULL s3c24x0”实际上便是履行了如下指令:

./mkconfigTX2440arm arm920t TX2410 NULL s3c24x0

行将“TX2440arm arm920t TX2440 NULL s3c24x0”作为参数传递给当时目录下的mkconfig脚本履行。

在mkconfig脚本中给出了mkconfig的用法:

#Parameters:TargetArchitectureCPUBoard[VENDOR][SOC]

因而传递给mkconfig的参数的含义分别是:

TX2440:Target(方针板类型)

arm:Architecture(方针板的CPU架构)

arm920t:CPU(详细运用的CPU类型)

TX2440:Board

NULL:VENDOR(生产厂家名)

s3c24x0:SOC

下面分步剖析mkconfig的效果:

(1)确认开发板的称号BOARD_NAME

APPEND=no #no表明创立新的装备文件,yes表明追加到装备文件中

BOARD_NAME=”” #Nametoprintinmakeoutput

TARGETS=””

while[$#-gt0];do

case”$1″in

–)shift;break;;

-a)shift;APPEND=yes;;

-n)shift;BOARD_NAME=”${1%%_config}”;shift;;

-t)shift;TARGETS=”`echo$1|seds:_::g`${TARGETS}”;shift;;

*)break;;

esac

done

[“${BOARD_NAME}”]||BOARD_NAME=”$1″

环境变量$#表明传递给脚本的参数个数,这儿的指令有6个参数,因而$#是6。shift的效果是使$1=$2,$2=$3,$3=$4….,而本来的$1将丢掉。因而while循环的效果是,顺次处理传递给mkconfig脚本的选项。因为咱们并没有传递给mkconfig任何的选项,因而while循环中的代码不起效果。

最终将BOARD_NAME的值设置为$1的值,在这儿便是“TX2440”。

(2)创立到渠道/开发板的头文件衔接

33 if[“$SRCTREE”!=”$OBJTREE”];then/******判别源代码目录和方针文件目录是否相同,能够挑选在其他目录下编译U-boot这可令代码目录坚持洁净。咱们运用的是直接在源代码目录下编译的,第33行不满足,跳到else分支的代码******/

45 else

46 cd./include

47 rm-fasm

48 ln-sasm-$2asm

49 fi

50

第46~48行进入include目录,删去asm文件(上一次装备时树立的链接文件),然后再次树立asm文件,并令它链向 asm-$2目录,即asm-arm.

51 rm-fasm-$2/arch

52

53 if[-z”$6″-o”$6″=”NULL”];then

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

55 else

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

57 fi

树立符号链接include/asm-arm/arch,若$6(SOC)为空,则使其链接到include/asm-arm/arch-arm920t目录,不然就使其链接到include/asm-arm/arch-s3c24x0目录。(事实上include/asm-arm/arch-arm920t并不存在,因而$6是不能为空的,不然会编译失利)

59 if[“$2″=”arm”];then

60 rm-fasm-$2/proc

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

62 fi

若方针板是arm架构,则上面的代码将树立符号衔接include/asm-arm/proc,使其链接到目录proc-armv目录。

树立以上的链接的优点:编译U-Boot时直接进入链接文件指向的目录进行编译,而不用依据不同开发板来挑选不同目录。

(3)创立顶层Makefile包含的文件include/config.mk

64 #

65 #CreateincludefileforMake

66 #

67 echo”ARCH=$2″>config.mk

68 echo”CPU=$3″>>config.mk

69 echo”BOARD=$4″>>config.mk

70

71 [“$5”]&&[“$5″!=”NULL”]&&echo”VENDOR=$5″>>config.mk

72

73 [“$6”]&&[“$6″!=”NULL”]&&echo”SOC=$6″>>config.mk

上面代码将会把如下内容写入文件inlcude/config.mk文件:

ARCH=arm

CPU=arm920t

BOARD=TX2440

SOC=s3c24x0

(4)创立开发板相关的头文件include/config.h

75 #

76 #Createboardspecificheaderfile

77 #

78 if[“$APPEND”=”yes”] #Appendtoexistingconfigfile

79 then

80 echo>>config.h

81 else

82 >config.h #Createnewconfigfile

83 fi

84 echo”/*Automaticallygenerated-donotedit*/”>>config.h

85 echo “#include “>>config.h

创立新的include/config.h文件。若APPEND为yes,则将新的装备内容追加到include/config.h文件后边。因为APPEND的值坚持“no”,因而config.h被创立了,内容如下:

/*Automaticallygenerated-donotedit*/

#include

下面总结指令makeTX2440_config履行的成果(仅针对编译方针输出到源代码目录的状况):

(1) 创立开发板称号BOARD_NAME等于$1

(2)创立到方针板相关的文件的链接

ln-sasm-armasm

ln-sarch-$6asm-$2/arch

ln-sproc-armvasm-arm/proc //假如$2不是arm,此行没有

(3)创立i顶层Makefile包含的文件 include/config.mk文件,内容如下所示:

ARCH=$2

CPU=$3

BOARD=$4

VENDOR=$5

SOC=$6

(4)创立与方针板相关的文件include/config.h,如下所示:

/*Automaticallygenerated-donotedit*/

#include

从这四个成果能够知道,假如要在board目录下新建一个开发板的目录,则在include/configs目录下也要树立一个文件,里边寄存的便是开发板的装备信息。

装备文件中有两类宏:一类是选项(option)前缀为“CONFIG_”它们用于挑选CPU、SOC、开发板类型、设置体系时钟、挑选设备驱动。

如:#define CONFIG_ARM920T1/* This is an ARM920T Core*/
#defineCONFIG_S3C24101/* in a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK24101/* on a SAMSUNG SMDK2410 Board */

另一类是参数(setting),前缀为“CFG_”,它们用于设置malloc缓冲池的巨细、U-BOOT提示符、U-boot下载文件时的默许加载地址、FLASH的开始地址等

如:#defineCFG_LONGHELP/* undef to save memory*/
#defineCFG_PROMPT”SMDK2410 # “/* Monitor Command Prompt*/
#defineCFG_CBSIZE256/* Console I/O Buffer Size*/
#defineCFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#defineCFG_MAXARGS16/* max number of command args*/
#define CFG_BARGSIZECFG_CBSIZE/* Boot Argument Buffer Size*/

能够这样以为,“CONFIG_”除了设置一些参数外,首要来设置U-Boot的功用、挑选运用文件中的哪一部分;而“CFG_”用来设置更细节的参数。

U-Boot的编译、链接进程

装备完后,履行“make all”既可编译,从Makefile中能够了解U-Boot运用了哪些文件、哪个文件首要履行、可履行文件占用内存状况。

若没有履行过“make_config”指令就直接履行“makeall”指令则会呈现如下的才错误信息,然后中止编译:

Systemnotconfigured-seeREADME

U-Boot是怎么知道用户没有履行过“make_config”指令的呢?阅览U-Boot源代码就能够发现了,Makefile中有如下代码:

ifeq($(obj)include/config.mk,$(wildcard$(obj)include/config.mk))#config.mk存在

all:

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

sinclude$(obj)include/autoconf.mk

……

else #config.mk不存在

……

@echo”Systemnotconfigured-seeREADME”>&2

@exit1

……

endif #config.mk

若include/config.mk文件存在,则$(wildcard$(obj)include/config.mk)指令履行的成果是“$(obj)include/config.mk”打开的字符串,不然成果为空。因为include/config.mk是“make_config”指令履行进程生成的,若从没有履行过“make_config”指令则include/config.mk必定不存在。因而Make就履行else分支的代码,在输出“Systemnotconfigured-seeREADME”的信息后就返回了。

117 include$(obj)include/config.mk

118 export ARCHCPUBOARDVENDORSOC

119

127 ifeq($(HOSTARCH),arm)

128 CROSS_COMPILE=arm-linux-

127 endif

163 #loadotherconfiguration

164 include$(TOPDIR)/config.mk

第117和164行用于包含其他的config.mk文件,第117行所包含的文件便是在上面的装备进程中制造出来的include/config.mk文件,其间界说了ARCH、CPU、BOARD、SOC等4个变量的值为arm、arm920t、TX2440、s3c24x0。第164行包含顶层的config.mk文件,它依据上面4个变量的值确认了编译器、编译选项。其间对咱们了解编译进程有协助的是BOARDDIR、LDFLAGS的值

#U-Bootobjects….orderisimportant(i.e.startmustbefirst)

169 OBJS=cpu/$(CPU)/start.o

LIBS+=cpu/$(CPU)/lib$(CPU).a

ifdefSOC

LIBS+=cpu/$(CPU)/$(SOC)/lib$(SOC).a

endif

ifeq($(CPU),ixp)

LIBS+=cpu/ixp/npe/libnpe.a

endif

LIBS+=lib_$(ARCH)/lib$(ARCH).a

LIBS+=fs/cramfs/libcramfs.afs/fat/libfat.afs/fdos/libfdos.afs/jffs2/libjffs2.a\

fs/reiserfs/libreiserfs.afs/ext2/libext2fs.afs/yaffs2/libyaffs2.a\

fs/ubifs/libubifs.a

……

LIBS+=common/libcommon.a

LIBS+=libfdt/libfdt.a

LIBS+=api/libapi.a

LIBS+=post/libpost.a

LIBS:=$(addprefix$(obj),$(LIBS))

LIBS变量指明晰U-Boot需求的库文件,包含渠道/开发板相关的目录、通用目录下相应的库,都经过相应的子目录编译得到的。

OBJS、LIBS所代表的.o、.a文件便是U-Boot的构成,他们经过如下指令由相应的源文件或相应的子目录下的文件编译得到

268 $(OBJS):
269 $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

271 $(LIBS):
272 $(MAKE) -C $(dir $(subst $(obj),,$@))

274 $(SUBDIRS):
275$(MAKE) -C $@ all

第268、269两行的规矩表明,关于OBJS中的每个成员,都将进入cpu/$(cpu)目录编译他们。现在OBJS为cpu/arm920t/start.o,它将由cpu/arm920t/start.s编译得到。第271、272两行规矩表明,关于LIBS中的每个成员,都将进入相应的子目录履行“make”指令。这些子目录中的Makefile,结构类似,他们将Makefile中指定的文件编译、链接成一个库文件。

当一切的OBJS、LIBS所表明的.o、.a文件都生成后就剩余链接了,这对用Makefile中如下代码

245 $(obj)u-boot.srec:$(obj)u-boot
246 $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@

248 $(obj)u-boot.bin:$(obj)u-boot
249$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

251 $(obj)u-boot.img:$(obj)u-boot.bin
./tools/mkimage -A $(ARCH) -T firmware -C none \
– a $(TEXT_BASE) -e 0 \
-n $(shell sed -n -e s/.*U_BOOT_VERSION//p $(VERSION_FILE) | \
sed -e s/”[ ]*$$/ for $(BOARD) board”/) \
-d $< $@

263 $(obj)u-boot.dis:$(obj)u-boot
254 $(OBJDUMP) -d $< > $@

265 $(obj)u-boot:depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e s/.*\(__u_boot_cmd_.*\)/-u\1/p|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
266 –start-group $(__LIBS) –end-group $(PLATFORM_LIBS) \
267 -Map u-boot.map -o u-boot

263到267的规矩链接到ELF格局的U-Boot,最终转换为二进制格局的U-Boot.bin、S-Record格局的U-Boot.srec。LDFLAGS确认了衔接的方法。(前面有说到)。

剖析完这些对移植的全体概括应该有了一个知道,了解其原理了。详细要修正什么就要依据实际需求了。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/272139.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部