引言:u-boot帮助我们启动内核,这个复杂的工作到底是怎么进行的,理解u-boot的源码流程,有助于我们对操作系统内核的理解
我们获取u-boot源码后,一般是解压,make <boardname>_config make all 。得到我们所要的u-boot.bin文件
现在来分析为什么要执行这些命令,已经这些命令做了什么工作。
一:分析命令Make 100ask24x0_config
1.vim Makefile-->/100ask..
2. (1)find:100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
(2)分析MKCONFIG--->/MKCONFIG
(3)MKCONFIG := $(SRCTREE)/mkconfig //MKCONFIG = ./mkconfig(当前目录下的mkconfig)
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0 ($#表示目标文件即100ask24x0_config,_config=空格即100ask24x0_config去掉_config)
替换: MKCONFIG 100ask24x0_config arm arm920t 100ask24x0 NULL s3c24x0
$0 $1 $2 $3 $4 $5 $6
(4)分析MKCONFIG 即分析mkconfig文件
mkconfig:
1.开发版名称
2.创建到平台/开发版相关的头文件的链接
3.创建顶层Makefile包含文件include/config.mk
4.创建开发版相关的头文件include/config.h
3.继续看Makefile文件
(1)117行include $(OBJTREE)/include/config.mk可以得知,我们刚才在mkconfig中生成的config,mk被会被Makefile用到
二:分析命令make
1.先make 100ask24x0_config make看结果
2.然后继续看Makefile的173行(行数+-10)
OBJS = cpu/$(CPU)/start.o 第一个目标文件,uboot执行的第一段代码就是start.S
OBJS+ = ..
.
.目标文件增加
.
LIBS = lib_generic/libgeneric.a 生成库文件 相当于把lib_generic/下的文件编译生成libgeneric.a一个库
LIBS+ = ..
. 库文件+
.
这里我们知道,Makefile链接了很多目标文件和编译生成库文件,为后面生成u-boot所用
3.到243行
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) //其中生成的目标文件u-boot.bin就是我们要的
all: $(ALL) -----就是 make命令执行(即make all),本句表示all依赖于ALL
到253行
$(obj)u-boot.bin: $(obj)u-boot
到266行
$(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) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
这句中OBJS和LIBS是我们上面分析的那些东西
4.make看最后的结果
结果和第3点的$(obj)u-boot: 结果相似
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
|
| 比较
|
UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /work/system/u-boot-1.1.6 && arm-linux-ld -Bstatic -T /work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \
--start-group lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a --end-group \
-Map u-boot.map -o u-boot(最后输出u-boot)
注意:LDFLAGS:
config.mk:189:LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
=-Ttext 0x33F80000
5.这么多链接文件,哪一个最先执行,我们从/work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds入手
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; //当前地址=0,加上前面-Ttext 0x33F80000 就是说下面的东西最开始从0x33F80000排放。其中 0x33F80000是在board/smdk2410(打补丁后是100ask24x0)/config.mk定义,如果你想让u-boot放在其他地址,在这里修改
(图片有错,应该是<0x33F80000,且SDRAM的地址为0x30000000——0x34000000)
. = ALIGN(4);
.text :
{
//第一个文件cpu/arm920t/start.S的代码段
cpu/arm920t/start.o (.text)
board/100ask24x0/boot_init.o (.text) //代码段
*(.text) //其他文件的代码段
}
. = ALIGN(4); //对齐
.rodata : { *(.rodata) }//只读数据段
. = ALIGN(4);
.data : { *(.data) }//数据段
. = ALIGN(4);
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) } //u-boot自定义的段
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
下面,我们来分析第一个文件cpu/arm920t/start.S