es/api
?
$(SUBDIRS): depend
$(MAKE) -C $@ all
执行tools ,examples/standalone ,examples/api目录下的Makefile。
3OBJS
OBJS的值是“cpu/arm920t/start.o”。它使用如下代码编译得到:
$(OBJS): depend
$(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
以上规则表明,对于OBJS包含的每个成员,都进入cpu/$(CPU)目录(即cpu/arm920t)编译它们。
4LIBBOARD
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
… …
$(LIBBOARD): depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
这里LIBBOARD的值是 $(obj)board/samsung/mini2440/libmini2440.a。make执行board/samsung/mini2440/目录下的Makefile,生成libmini2440.a 。
5LIBS
LIBS变量中的每个元素使用如下的规则编译得到:
$(LIBS): depend $(SUBDIRS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
上面的规则表明,对于LIBS中的每个成员,都进入相应的子目录执行“make”命令编译它们。例如对于LIBS中的“common/libcommon.a”成员,程序将进入common目录执行Makefile,生成libcommon.a 。
6LDSCRIPT
LDSCRIPT := $(SRCTREE)/cpu/$(CPU)/u-boot.lds
… …
$(LDSCRIPT): depend
$(MAKE) -C $(dir $@) $(notdir $@)
“$(MAKE) -C $(dir $@) $(notdir $@)”命令经过变量替换后就是“make -C cpu/arm920t/ u-boot.lds”。也就是转到cpu/arm920t/目录下,执行“make u-boot.lds”命令。
7$(obj)u-boot.lds
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
以上执行结果实质上是将cpu/arm920t/u-boot.lds经编译器简单预处理后输出到U-Boot顶层目录下的u-boot.lds文件。其中的cpu/arm920t/u-boot.lds文件内容如下:
/* 输出为ELF文件,小端方式, */
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
?
. = ALIGN(4);
.text :
{
/* cpu/arm920t/start.o放在最前面,保证最先执行的是start.o */
cpu/arm920t/start.o (.text)
/*以下2个文件必须放在前4K,因此也放在前面,其中board/samsung/mini2440/lowlevel_init.o 包含内存初始化所需代码,而board/samsung/mini2440/nand_read.o 包含U-Boot从NAND Flash搬运自身的代码 */
board/samsung/mini2440/lowlevel_init.o (.text)
board/samsung/mini2440/nand_read.o (.text)
/* 其他文件的代码段 */
*(.text)
}
?
/* 只读数据段 */
. = 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指定为当前地址 */
.u_boot_cmd : { *(.u_boot_cmd) } /* 存放所有U-Boot命令对应的cmd_tbl_t结构体 */
__u_boot_cmd_end = .; /* 将__u_boot_cmd_end指定为当前地址 */
?
/* bss段 */
. = ALIGN(4);
__bss_start = .;
.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
_end = .; /* 将_end指定为当前地址 */
}
u-boot.lds实质上是U-Boot连接脚本。对于生成的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 vaddr 0x33f80000 paddr 0x33f80000 align 2**15
filesz 0x0002f99c memsz 0x00072c94 flags rwx
STACK off 0x00000000 vaddr 0x00000000 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启动阶段复制代码到RAM空间的过程以及U-Boot命令执行过程密切相关,具体请结合U-Boot源代码理解。
编