uboot-spl编译流程
[uboot] (第二章)uboot流程——uboot-spl編譯流程
2016年10月27日 20:40:47閱讀數(shù):2675以下例子都以project X項(xiàng)目tiny210(s5pv210平臺(tái),armv7架構(gòu))為例
[uboot] uboot流程系列:?
[project X] tiny210(s5pv210)上電啟動(dòng)流程(BL0-BL2)
建議先看《[project X] tiny210(s5pv210)上電啟動(dòng)流程(BL0-BL2)》,根據(jù)例子了解一下上電之后的BL0\BL1\BL2階段,以及各個(gè)階段的運(yùn)行位置,功能。
=================================================================================
一、uboot-spl編譯和生成文件
spl的編譯是編譯uboot的一部分,和uboot.bin走的是兩條編譯流程,這個(gè)要重點(diǎn)注意。?
正常來(lái)說(shuō),會(huì)先編譯主體uboot,也就是uboot.bin.再編譯uboot-spl,也就是uboot-spl.bin,雖然編譯命令是一起的,但是編譯流程是分開(kāi)的。
1、編譯方法
在project X項(xiàng)目中,所有鏡像,包括uboot、kernel、rootfs都是放在build目錄下進(jìn)行編譯的。具體去參考該項(xiàng)目build的Makefile的實(shí)現(xiàn)。?
假設(shè)config已經(jīng)配置完成,在build編譯命令如下:
- 1
Makefile中對(duì)應(yīng)的命令如下:
BUILD_DIR=$(shell pwd) OUT_DIR=$(BUILD_DIR)/out UBOOT_OUT_DIR=$(OUT_DIR)/u-boot UBOOT_DIR=$(BUILD_DIR)/../u-boot uboot:mkdir -p $(UBOOT_OUT_DIR)make -C $(UBOOT_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(UBOOT_OUT_DIR) $(BOARD_NAME)_defconfigmake -C $(UBOOT_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(UBOOT_OUT_DIR) ## -C $(UBOOT_DIR) 指定了要在../uboot,也就是uboot的代碼根目錄下執(zhí)行make ## CROSS_COMPILE=$(CROSS_COMPILE) 指定了交叉編譯器 ## KBUILD_OUTPUT=$(UBOOT_OUT_DIR) 指定了最終編譯的輸出目錄是build/out/u-boot.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
最終,相當(dāng)于進(jìn)入了uboot目錄執(zhí)行了make動(dòng)作。?
也就是說(shuō)spl的編譯是編譯uboot的一部分,和uboot.bin走的是兩條編譯流程,這個(gè)要重點(diǎn)注意。?
正常來(lái)說(shuō),會(huì)先編譯主體uboot,也就是uboot.bin.再編譯uboot-spl,也就是uboot-spl.bin,雖然編譯命令是一起的,但是編譯流程是分開(kāi)的。
2、生成文件?
最終編譯完成之后,會(huì)在project-x/build/out/u-boot/spl下生成如下文件:
- 1
- 2
其中,arch、common、dts、include、board、drivers、fs是對(duì)應(yīng)代碼的編譯目錄,各個(gè)目錄下都會(huì)生成相應(yīng)的built.o,是由同目錄下的目標(biāo)文件連接而成。?
重點(diǎn)說(shuō)一下以下幾個(gè)文件:
| u-boot-spl | 初步鏈接后得到的spl文件 |
| u-boot-spl-nodtb.bin | 在u-boot-spl的基礎(chǔ)上,經(jīng)過(guò)objcopy去除符號(hào)表信息之后的可執(zhí)行程序 |
| u-boot-spl.bin | 在不需要dtb的情況下,直接由u-boot-spl-nodtb.bin復(fù)制而來(lái),也就是編譯spl的最終目標(biāo) |
| tiny210-spl.bin | 由s5pv210平臺(tái)決定,需要在u-boot-spl.bin的基礎(chǔ)上加上16B的header用作校驗(yàn) |
| u-boot-spl.lds | spl的連接腳本 |
| u-boot-spl.map | 連接之后的符號(hào)表文件 |
| u-boot-spl.cfg | 由spl配置生成的文件 |
二、uboot-spl編譯流程
1、編譯整體流程
根據(jù)零、2生成的文件說(shuō)明可知簡(jiǎn)單流程如下:?
(1)各目錄下built-in.o的生成
對(duì)應(yīng)二、2(5)的實(shí)現(xiàn)?
(2)由所有built-in.o以u(píng)-boot-spl.lds為連接腳本通過(guò)連接來(lái)生成u-boot-spl
對(duì)應(yīng)二、2(4)的實(shí)現(xiàn)?
(3)由u-boot-spl生成u-boot-spl-nodtb.bin
對(duì)應(yīng)二、2(3)的實(shí)現(xiàn)?
(4)由u-boot-spl-nodtb.bin生成u-boot-spl.bin,也就是spl的bin文件
對(duì)應(yīng)二、2(2)的實(shí)現(xiàn)
后續(xù)的編譯的核心過(guò)程就是按照上述的四個(gè)編譯流程就是按照上述四個(gè)步驟來(lái)的。
2、具體編譯流程分析
我們直接從make uboot命令分析,也就是從uboot下的Makefile的依賴(lài)關(guān)系來(lái)分析整個(gè)編譯流程。?
注意,這個(gè)分析順序和上述的整體編譯流程的順序是反著的。
- (1)入口分析?
在project-x/u-boot/Makefile中
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
綜上,由CONFIG_SPL來(lái)決定是否需要編譯出spl文件,也就是BL1。?
后續(xù)相當(dāng)于執(zhí)行了?“make -f u-boot/scripts/Makefile.spl obj=spl all”?命令。?
在project-x/u-boot/scripts/Makefile.spl中,
- 1
- 2
- 3
在project-x/u-boot/scripts/Makefile.spl中建立了spl/u-boot-spl.bin的依賴(lài)關(guān)系,后續(xù)make過(guò)程的主體都是在Makefile.spl中。
- (2)spl/u-boot-spl.bin的依賴(lài)關(guān)系
在project-x/u-boot/scripts/Makefile.spl中
$(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-nodtb.bin FORCE$(call if_changed,copy) ## $(obj)/$(SPL_BIN).bin依賴(lài)于$(obj)/$(SPL_BIN)-nodtb.bin。 ## $(call if_changed,copy)表示當(dāng)依賴(lài)文件發(fā)生變化時(shí),直接把依賴(lài)文件復(fù)制為目標(biāo)文件,即直接把$(obj)/$(SPL_BIN)-nodtb.bin復(fù)制為$(obj)/$(SPL_BIN).bin- 1
- 2
- 3
- 4
如上述Makefile代碼spl/u-boot-spl.bin依賴(lài)于spl/u-boot-spl-nodtb.bin,并且由spl/u-boot-spl-nodtb.bin復(fù)制而成。?
對(duì)應(yīng)于上述二、1(4)流程。
- (3)spl/u-boot-spl-nodtb.bin的依賴(lài)關(guān)系?
在project-x/u-boot/scripts/Makefile.spl中
- 1
- 2
- 3
- 4
- 5
如上述Makefile代碼spl/u-boot-spl-nodtb.bin依賴(lài)于spl/u-boot-spl,并且由spl/u-boot-spl經(jīng)過(guò)objcopy操作之后得到。?
對(duì)應(yīng)于上述二、1(3)流程。
- (4)spl/u-boot-spl的依賴(lài)關(guān)系?
在project-x/u-boot/scripts/Makefile.spl中
- 1
- 2
- 3
- 4
如上,spl/u-boot-spl依賴(lài)于$(u-boot-spl-init) 、$(u-boot-spl-main)和spl/u-boot-spl.ld,并且最終會(huì)調(diào)用cmd_u-boot-spl來(lái)生成spl/u-boot-spl。?
cmd_u-boot-spl實(shí)現(xiàn)如下:
- 1
- 2
- 3
- 4
- 5
將cmd_u-boot-spl通過(guò)echo命令打印出來(lái)之后得到如下(拆分出來(lái)看的):
cmd_u-boot-spl=( cd spl && /build/arm-none-linux-gnueabi-4.8/bin/arm-none-linux-gnueabi-ld -T u-boot-spl.lds --gc-sections -Bstatic --gc-sections arch/arm/cpu/armv7/start.o --start-group arch/arm/mach-s5pc1xx/built-in.o arch/arm/cpu/armv7/built-in.o arch/arm/cpu/built-in.o arch/arm/lib/built-in.o board/samsung/tiny210/built-in.o board/samsung/common/built-in.o common/init/built-in.o drivers/built-in.o dts/built-in.o fs/built-in.o --end-group arch/arm/lib/eabi_compat.o -L /home/disk3/xys/temp/project-x/build/arm-none-linux-gnueabi-4.8/bin/../lib/gcc/arm-none-linux-gnueabi/4.8.3 -lgcc -Map u-boot-spl.map -o u-boot-spl)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
可以看出上述是一條連接命令,以spl/u-boot-spl.ld為鏈接腳本,把$(u-boot-spl-init) 、$(u-boot-spl-main)的指定的目標(biāo)文件連接到u-boot-spl中。?
連接很重要的東西就是連接標(biāo)識(shí),也就是?$(LD)?$(LDFLAGS)?$(LDFLAGS_$(@F)的定義。?
嘗試把$(LD) \$(LDFLAGS) \$(LDFLAGS_\$(@F)) 打印出來(lái),結(jié)果如下:
- 1
- 2
- 3
- 4
也就是說(shuō)在LDFLAGS_u-boot-spl中指定了鏈接腳本。?
重點(diǎn)關(guān)注$(LDFLAGS_$(@F))的由來(lái)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- (5)u-boot-spl-init & u-boot-spl-main依賴(lài)關(guān)系(代碼是如何被編譯的)?
先看一下這兩個(gè)值打印出來(lái)的
- 1
- 2
- 3
可以觀察到是一堆目標(biāo)文件的路徑。這些目標(biāo)文件最終都要被連接到u-boot-spl中。?
u-boot-spl-init & u-boot-spl-main的定義如下代碼:?
project-x/u-boot/scripts/Makefile.spl
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
那么u-boot-spl-init & u-boot-spl-main是如何生成的呢??
需要看一下對(duì)應(yīng)的依賴(lài)如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
也就是會(huì)對(duì)每一個(gè)目標(biāo)文件依次執(zhí)行make?$(build)=目標(biāo)文件?
$(build)定義如下:?
project-x/u-boot/scripts/Kbuild.include
- 1
以arch/arm/mach-s5pc1xx為例?
“$(MAKE)?$(build)=$@”展開(kāi)后格式如下?
make -f ~/code/temp/project-x/u-boot/scripts/Makefile.build obj=spl/arch/arm/mach-s5pc1xx。
Makefile.build定義built-in.o、.lib以及目標(biāo)文件.o的生成規(guī)則。這個(gè)Makefile文件生成了子目錄的.lib、built-in.o以及目標(biāo)文件.o。?
Makefile.build第一個(gè)編譯目標(biāo)是__build,如下
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
對(duì)應(yīng)于上述二、1(1)流程。
- (6)spl/u-boot-spl.lds依賴(lài)關(guān)系?
這里主要是為了找到一個(gè)匹配的連接文件。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
綜上,最終指定了project-X/u-boot/arch/arm/cpu/u-boot-spl.lds作為連接腳本。
三、一些重點(diǎn)定義
1、CONFIG_SPL?
在二、2(1)中說(shuō)明。?
用于指定是否需要編譯SPL,也就是是否需要編譯出uboot-spl.bin文件2、連接腳本的位置?
在二、2(6)中說(shuō)明。?
對(duì)于tiny210(s5pv210 armv7)來(lái)說(shuō),連接腳本的位置在?
project-x/u-boot/arch/arm/cpu/u-boot-spl.lds3、CONFIG_SPL_TEXT_BASE?
在二、2(4)中說(shuō)明。?
用于指定SPL的連接地址,可以定義在板子對(duì)應(yīng)的config文件中。4、CONFIG_SPL_BUILD?
在編譯spl過(guò)程中,會(huì)配置?
project-x/scripts/Makefile.spl中定義了如下
- 1
也就是說(shuō)在編譯uboot-spl.bin的過(guò)程中,CONFIG_SPL_BUILD這個(gè)宏是被定義的。
四、uboot-spl鏈接腳本說(shuō)明
1、連接腳本整體分析
相對(duì)比較簡(jiǎn)單,直接看連接腳本的內(nèi)容project-x/u-boot/arch/arm/cpu/u-boot-spl.lds?
前面有一篇分析連接腳本的文章了《[kernel 啟動(dòng)流程] 前篇——vmlinux.lds分析》,可以參考一下。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
2、符號(hào)表中需要注意的符號(hào)
project-x/build/out/u-boot/spl/u-boot-spl.map
Linker script and memory map .text 0x00000000 0xd100x00000000 __image_copy_start = . *(.vectors)0x00000000 _start0x00000020 _undefined_instruction0x00000024 _software_interrupt0x00000028 _prefetch_abort0x0000002c _data_abort0x00000030 _not_used0x00000034 _irq0x00000038 _fiq ...0x00000d10 __image_copy_end = . .rel.dyn 0x00000d10 0x00x00000d10 __rel_dyn_start = .*(.rel*).rel.iplt 0x00000000 0x0 arch/arm/cpu/armv7/start.o0x00000d10 __rel_dyn_end = . .end*(.__end)0x00000d10 _image_binary_end = ..bss 0x00000d10 0x00x00000d10 __bss_start = .*(.bss*)0x00000d10 . = ALIGN (0x4)0x00000d10 __bss_end = .- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
重點(diǎn)關(guān)注?
* __image_copy_start & __image_copy_end?
界定了代碼的位置,用于重定向代碼的時(shí)候使用,后面碰到了再分析。?
* _start?
在u-boot-spl.lds中ENTRY(_start),也就規(guī)定了代碼的入口函數(shù)是_start。所以后續(xù)分析代碼的時(shí)候就是從這里開(kāi)始分析。?
* __rel_dyn_start & __rel_dyn_end?
* _image_binary_end
五、tiny210(s5pv210)的額外操作
1、為什么tiny210的spl需要額外操作?需要什么額外操作?
建議先參考《[project X] tiny210(s5pv210)上電啟動(dòng)流程(BL0-BL2)》一文。?
tiny210只支持SD啟動(dòng)的方式和NAND FLASH啟動(dòng)的方式。?
從《[project X] tiny210(s5pv210)上電啟動(dòng)流程(BL0-BL2)》一文中,我們已經(jīng)得知了當(dāng)使用SD啟動(dòng)的方式和NAND FLASH啟動(dòng)的方式,也就是BL1鏡像存放在SD上或者nand flash上時(shí),s5pv210中固化的BL0,都需要對(duì)BL1的前16B的header做校驗(yàn)。BL1就是我們所說(shuō)的uboot-spl.bin,但是默認(rèn)編譯出來(lái)的uboot-spl.bin就是一個(gè)純粹的可執(zhí)行文件,并沒(méi)有加上特別的header。?
因此,我們需要在生成uboot-spl.bin之后,再為其加上16B的header后生成tiny210-spl.bin。?
16B的header格式如下:
| 0xD002_0000 | BL1鏡像包括header的長(zhǎng)度 |
| 0xD002_0004 | 保留,設(shè)置為0 |
| 0xD002_0008 | BL1鏡像除去header的校驗(yàn)和 |
| 0xD002_000c | 保留,設(shè)置為0 |
2、如何生成header?(如何生成tiny210-spl.bin)
project-x/u-boot/scripts/Makefile.spl
ifdef CONFIG_SAMSUNG ALL-y += $(obj)/$(BOARD)-spl.bin endif ## 當(dāng)平臺(tái)是SAMSUNG平臺(tái)的時(shí)候,也就是CONFIG_SAMSUNG被定義的時(shí)候,就需要生成對(duì)應(yīng)的板級(jí)spl.bin文件,例如tiny210的話,就應(yīng)該生成對(duì)應(yīng)的spl/tiny210-spl.bin文件。ifdef CONFIG_S5PC110 $(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin$(objtree)/tools/mks5pc1xxspl $< $@ ## 如果是S5PC110系列的cpu的話,則使用如上方法打上header。tiny210的cpu是s5pv210的,屬于S5PC110系列,所以走的是這路。 ## $(objtree)/tools/mks5pc1xxspl對(duì)應(yīng)于編譯uboot時(shí)生成的build/out/u-boot/tools/mks5pc1xxspl ## 其代碼路徑位于u-boot/tools/mks5pc1xxspl.c,會(huì)根據(jù)s5pc1xx系列的header規(guī)則為輸入bin文件加上16B的header,具體參考代碼。 ## 這里就構(gòu)成了u-boot-spl.bin到tiny210-spl.bin的過(guò)程了。 else $(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin$(if $(wildcard $(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl),\$(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl,\$(objtree)/tools/mkexynosspl) $(VAR_SIZE_PARAM) $< $@ endif endif- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
這里就構(gòu)成了u-boot-spl.bin到tiny210-spl.bin的過(guò)程了。
綜上,spl的編譯就完成了。
總結(jié)
以上是生活随笔為你收集整理的uboot-spl编译流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: UBOOT 概述
- 下一篇: 1-uboot流程——概述