<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > uboot移植詳解

uboot移植詳解

作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò ) 收藏
參考:

嵌入式Linux應用開(kāi)發(fā)完全手冊》 韋東山編著(zhù) 第15章 移植 U-boot

本文引用地址:http://dyxdggzs.com/article/201611/316102.htm

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

uboot是一段小程序,它在系統上電是開(kāi)始執行,初始化硬件設備;準備好軟件環(huán)境;最后調用操作系統內核。

這里主要分析移植過(guò)程。

U-boot中有幾千個(gè)文件,要想了解對于某款開(kāi)發(fā)板,使用哪些文件、哪個(gè)文件先執行、可執行文件占用內存的情況,最好的方法就是閱讀它的Makefile文件。

要想使用哪款開(kāi)發(fā)板就需首先執行“make _config”命令進(jìn)行配置,然后執行“make all”就可生成三個(gè)文件,分別是:

U-Boot.bin:二進(jìn)制可執行文件,可直接燒入ROM、NORFLASH

U-Boot.elf

U-Boot.srec:Motorola S-Record格式的可執行文件

U-Boot編譯命令

對于TX2440開(kāi)發(fā)板,編譯U-Boot需要執行如下的命令:

$makeTX2440_config

$makeall

使用上面的命令編譯U-Boot,編譯生成的所有文件都保存在源代碼目錄中。為了保持源代碼目錄的干凈,可以使用如下命令將編譯生成的文件輸出到一個(gè)外部目錄,而不是在源代碼目錄中,下面的2種方法都將編譯生成的文件輸出到/tmp/build目錄:

$exportBUILD_DIR=/tmp/build

$makeTX2440_config

$makeall

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

$makeall

makeTX2440_config命令執行過(guò)程

下面分析命令“makeTX2440_config”執行過(guò)程,為了簡(jiǎn)化分析過(guò)程這里主要分析將編譯目標輸出到源代碼目錄的情況。

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

其中的依賴(lài)“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

其中“@”的作用是執行該命令時(shí)不在shell顯示。“obj”變量就是編譯輸出的目錄,因此“unconfig”的作用就是清除上次執行make*_config命令生成的配置文件(如include/config.h,include/config.mk等)。

$(MKCONFIG)在上面指定為“$(SRCTREE)/mkconfig”。$(@:_config=)為將傳進(jìn)來(lái)的所有參數中的_config替換為空(其中“@”指規則的目標文件名,在這里就是“TX2440_config”。$(text:patternA=patternB),這樣的語(yǔ)法表示把text變量每一個(gè)元素中結尾的patternA的文本替換為patternB,然后輸出)。因此$(@:_config=)的作用就是將TX2440_config中的_config去掉,得到TX2440。

因此@$(MKCONFIG) $(@:_config=) arm arm920t TX2440 NULL s3c24x0”實(shí)際上就是執行了如下命令:

./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(生產(chǎn)廠(chǎng)家名)

s3c24x0:SOC

下面分步分析mkconfig的作用:

(1)確定開(kāi)發(fā)板的名稱(chēng)BOARD_NAME

APPEND=no #no表示創(chuàng )建新的配置文件,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"

環(huán)境變量$#表示傳遞給腳本的參數個(gè)數,這里的命令有6個(gè)參數,因此$#是6。shift的作用是使$1=$2,$2=$3,$3=$4….,而原來(lái)的$1將丟失。因此while循環(huán)的作用是,依次處理傳遞給mkconfig腳本的選項。由于我們并沒(méi)有傳遞給mkconfig任何的選項,因此while循環(huán)中的代碼不起作用。

最后將BOARD_NAME的值設置為$1的值,在這里就是“TX2440”。

(2)創(chuàng )建到平臺/開(kāi)發(fā)板的頭文件連接

33 if["$SRCTREE"!="$OBJTREE"];then/******判斷源代碼目錄和目標文件目錄是否一樣,可以選擇在其他目錄下編譯U-boot這可令代碼目錄保持干凈。我們使用的是直接在源代碼目錄下編譯的,第33行不滿(mǎn)足,跳到else分支的代碼******/

45 else

46 cd./include

47 rm-fasm

48 ln-sasm-$2asm

49 fi

50

第46~48行進(jìn)入include目錄,刪除asm文件(上一次配置時(shí)建立的鏈接文件),然后再次建立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目錄。(事實(shí)上include/asm-arm/arch-arm920t并不存在,因此$6是不能為空的,否則會(huì )編譯失?。?/p>

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時(shí)直接進(jìn)入鏈接文件指向的目錄進(jìn)行編譯,而不必根據不同開(kāi)發(fā)板來(lái)選擇不同目錄。

(3)創(chuàng )建頂層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

上面代碼將會(huì )把如下內容寫(xiě)入文件inlcude/config.mk文件:

ARCH=arm

CPU=arm920t

BOARD=TX2440

SOC=s3c24x0

(4)創(chuàng )建開(kāi)發(fā)板相關(guān)的頭文件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

創(chuàng )建新的include/config.h文件。若APPEND為yes,則將新的配置內容追加到include/config.h文件后面。由于A(yíng)PPEND的值保持“no”,因此config.h被創(chuàng )建了,內容如下:

/*Automaticallygenerated-donotedit*/

#include

下面總結命令makeTX2440_config執行的結果(僅針對編譯目標輸出到源代碼目錄的情況):

(1) 創(chuàng )建開(kāi)發(fā)板名稱(chēng)BOARD_NAME等于$1

(2)創(chuàng )建到目標板相關(guān)的文件的鏈接

ln-sasm-armasm

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

ln-sproc-armvasm-arm/proc //如果$2不是arm,此行沒(méi)有

(3)創(chuàng )建i頂層Makefile包含的文件 include/config.mk文件,內容如下所示:

ARCH=$2

CPU=$3

BOARD=$4

VENDOR=$5

SOC=$6

(4)創(chuàng )建與目標板相關(guān)的文件include/config.h,如下所示:

/*Automaticallygenerated-donotedit*/

#include

從這四個(gè)結果可以知道,如果要在board目錄下新建一個(gè)開(kāi)發(fā)板的目錄,則在include/configs目錄下也要建立一個(gè)文件,里面存放的就是開(kāi)發(fā)板的配置信息。

配置文件中有兩類(lèi)宏:一類(lèi)是選項(option)前綴為“CONFIG_”它們用于選擇CPU、SOC、開(kāi)發(fā)板類(lèi)型、設置系統時(shí)鐘、選擇設備驅動(dòng)。

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

另一類(lèi)是參數(setting),前綴為“CFG_”,它們用于設置malloc緩沖池的大小、U-BOOT提示符、U-boot下載文件時(shí)的默認加載地址、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_”除了設置一些參數外,主要來(lái)設置U-Boot的功能、選擇使用文件中的哪一部分;而“CFG_”用來(lái)設置更細節的參數。

U-Boot的編譯、鏈接過(guò)程

配置完后,執行“make all”既可編譯,從Makefile中可以了解U-Boot使用了哪些文件、哪個(gè)文件首先執行、可執行文件占用內存情況。

若沒(méi)有執行過(guò)“make_config”命令就直接執行“makeall”命令則會(huì )出現如下的才錯誤信息,然后停止編譯:

Systemnotconfigured-seeREADME

U-Boot是如何知道用戶(hù)沒(méi)有執行過(guò)“make_config”命令的呢?閱讀U-Boot源代碼就可以發(fā)現了,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”展開(kāi)的字符串,否則結果為空。由于include/config.mk是“make_config”命令執行過(guò)程生成的,若從沒(méi)有執行過(guò)“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行所包含的文件就是在上面的配置過(guò)程中制造出來(lái)的include/config.mk文件,其中定義了ARCH、CPU、BOARD、SOC等4個(gè)變量的值為arm、arm920t、TX2440、s3c24x0。第164行包含頂層的config.mk文件,它根據上面4個(gè)變量的值確定了編譯器、編譯選項。其中對我們理解編譯過(guò)程有幫助的是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需要的庫文件,包括平臺/開(kāi)發(fā)板相關(guān)的目錄、通用目錄下相應的庫,都通過(guò)相應的子目錄編譯得到的。

OBJS、LIBS所代表的.o、.a文件就是U-Boot的構成,他們通過(guò)如下命令由相應的源文件或相應的子目錄下的文件編譯得到

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中的每個(gè)成員,都將進(jìn)入cpu/$(cpu)目錄編譯他們?,F在OBJS為cpu/arm920t/start.o,它將由cpu/arm920t/start.s編譯得到。第271、272兩行規則表示,對于LIBS中的每個(gè)成員,都將進(jìn)入相應的子目錄執行“make”命令。這些子目錄中的Makefile,結構相似,他們將Makefile中指定的文件編譯、鏈接成一個(gè)庫文件。

當所有的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_.*)/-u1/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,最后轉換為二進(jìn)制格式的U-Boot.bin、S-Record格式的U-Boot.srec。LDFLAGS確定了連接的方式。(前面有提到)。

分析完這些對移植的整體輪廓應該有了一個(gè)認識,了解其原理了。具體要修改什么就要根據實(shí)際需要了。



關(guān)鍵詞: uboot移植詳

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>