下面分析$(obj)u-boot的各個(gè)依賴:
1依賴目標(biāo)depend
# Explicitly make _depend in subdirscontaining multiple targets to prevent
# parallel sub-makes creating .depend filessimultaneously.
depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk
fordir in $(SUBDIRS) cpu/$(CPU) $(dir $(LDSCRIPT)) ; do \
$(MAKE)-C $$dir _depend ; done
對(duì)于$(SUBDIRS),cpu/$(CPU),$(dir $(LDSCRIPT))中的每個(gè)元素都進(jìn)入該目錄執(zhí)行“make_depend”,生成各個(gè)子目錄的.depend文件,.depend列出每個(gè)目標(biāo)文件的依賴文件。
2依賴SUBDIRS
SUBDIRS = tools \
examples/standalone \
examples/api
$(SUBDIRS): depend
$(MAKE)-C $@ all
執(zhí)行tools ,examples/standalone ,examples/api目錄下的Makefile。
3OBJS
OBJS的值是“cpu/arm920t/start.o”。它使用如下代碼編譯得到:
$(OBJS): depend
$(MAKE)-C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
以上規(guī)則表明,對(duì)于OBJS包含的每個(gè)成員,都進(jìn)入cpu/$(CPU)目錄(即cpu/arm920t)編譯它們。
4LIBBOARD
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
LIBBOARD := $(addprefix$(obj),$(LIBBOARD))
… …
$(LIBBOARD): depend $(LIBS)
$(MAKE)-C $(dir $(subst $(obj),,$@))
這里L(fēng)IBBOARD的值是$(obj)board/samsung/mini2440/libmini2440.a。make執(zhí)行board/samsung/mini2440/目錄下的Makefile,生成libmini2440.a 。
5LIBS
LIBS變量中的每個(gè)元素使用如下的規(guī)則編譯得到:
$(LIBS): depend$(SUBDIRS)
$(MAKE)-C $(dir $(subst $(obj),,$@))
上面的規(guī)則表明,對(duì)于LIBS中的每個(gè)成員,都進(jìn)入相應(yīng)的子目錄執(zhí)行“make”命令編譯它們。例如對(duì)于LIBS中的“common/libcommon.a”成員,程序?qū)⑦M(jìn)入common目錄執(zhí)行Makefile,生成libcommon.a 。
6LDSCRIPT
LDSCRIPT := $(SRCTREE)/cpu/$(CPU)/u-boot.lds
… …
$(LDSCRIPT): depend
$(MAKE)-C $(dir $@) $(notdir $@)
“$(MAKE) -C $(dir $@)$(notdir $@)”命令經(jīng)過變量替換后就是“make-C cpu/arm920t/ u-boot.lds”。也就是轉(zhuǎn)到cpu/arm920t/目錄下,執(zhí)行“make u-boot.lds”命令。
7$(obj)u-boot.lds
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP)$(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - 《$^ 》$@
以上執(zhí)行結(jié)果實(shí)質(zhì)上是將cpu/arm920t/u-boot.lds經(jīng)編譯器簡(jiǎn)單預(yù)處理后輸出到U-Boot頂層目錄下的u-boot.lds文件。其中的cpu/arm920t/u-boot.lds文件內(nèi)容如下:
/* 輸出為ELF文件,小端方式, */
OUTPUT_FORMAT(“elf32-littlearm”,“elf32-littlearm”, “elf32-littlearm”)
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
。= 0x00000000;
。= ALIGN(4);
.text:
{
/* cpu/arm920t/start.o放在最前面,保證最先執(zhí)行的是start.o */
cpu/arm920t/start.o (.text)
/*以下2個(gè)文件必須放在前4K,因此也放在前面,其中board/samsung/mini2440/lowlevel_init.o包含內(nèi)存初始化所需代碼,而board/samsung/mini2440/nand_read.o 包含U-Boot從NAND Flash搬運(yùn)自身的代碼 */
board/samsung/mini2440/lowlevel_init.o(.text)
board/samsung/mini2440/nand_read.o(.text)
/* 其他文件的代碼段 */
*(.text)
}
/* 只讀數(shù)據(jù)段 */
。= ALIGN(4);
.rodata: { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
/* 代碼段 */
。= ALIGN(4);
.data: { *(.data) }
/* u-boot自定義的got段 */
。= ALIGN(4);
.got: { *(.got) }
。= 。;
__u_boot_cmd_start= 。; /*將 __u_boot_cmd_start指定為當(dāng)前地址 */
.u_boot_cmd: { *(.u_boot_cmd) } /* 存放所有U-Boot命令對(duì)應(yīng)的cmd_tbl_t結(jié)構(gòu)體 */
__u_boot_cmd_end= 。; /* 將__u_boot_cmd_end指定為當(dāng)前地址 */
/* bss段 */
。= ALIGN(4);
__bss_start= 。;
.bss(NOLOAD) : { *(.bss) 。 = ALIGN(4); }
_end= 。; /* 將_end指定為當(dāng)前地址 */
}
u-boot.lds實(shí)質(zhì)上是U-Boot連接腳本。對(duì)于生成的U-Boot編譯生成的“u-boot”文件,可以使用objdump命令可以查看它的分段信息:
$ objdump -x u-boot | more
部分輸出信息如下:
u-boot: file format elf32-little
u-boot
architecture: UNKNOWN!, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x33f80000
Program Header:
LOAD off 0x00008000 vaddr0x33f80000 paddr 0x33f80000 align 2**15
filesz 0x0002f99c memsz 0x00072c94 flags rwx
STACK off 0x00000000 vaddr0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rwx
Sections:
Idx Name Size VMA LMA File off Algn
0.text 00024f50 33f80000 33f80000 00008000 2**5
CONTENTS, ALLOC, LOAD,READONLY, CODE
1.rodata 00008b78 33fa4f50 33fa4f50 0002cf50 2**3
CONTENTS, ALLOC, LOAD, READONLY,DATA
2.data 00001964 33fadac8 33fadac8 00035ac8 2**2
CONTENTS, ALLOC, LOAD, DATA
3.u_boot_cmd 00000570 33faf42c 33faf42c 0003742c 2**2
CONTENTS, ALLOC, LOAD, DATA
4.bss 00043294 33fafa00 33fafa00 0003799c 2**8
ALLOC
… …
u-boot.lds還跟U-Boot啟動(dòng)階段復(fù)制代碼到RAM空間的過程以及U-Boot命令執(zhí)行過程密切相關(guān),具體請(qǐng)結(jié)合U-Boot源代碼理解。
評(píng)論
查看更多