1. 了解u-boot主要的目录结构和启动流程,如下图。
u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;
u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。
各个部分的流程图如下:
2. u-boot源码分析——Makefile简要分析
u-boot下所有目录的编译连接都是由顶层目录的Makefile来决定的。在执行make之前,先要执行 make $(board)_config 对工程进行配置,以确定特定于目标板的各个子目录和头文件。$(board)_config 是Makefile 中的一个伪目标,它传入指定的CPU,ARCH,BOARD,SOC参数去执行mkconfig脚本。这个脚本的主要功能在于连接目标板平台相关的头文件夹,生成config.h文件包含板子的配置头文件,使得Makefile能根据目标板的这些参数去编译正确的平台相关的子目录。
以smdk2410为例:make smdk2410_config
该配置主要完成以下三个功能:
(1)在include文件夹下建立相应的文件(夹)软连接;
#ln -s asm-arm asm
#ln -s arch-s3c24x0 asm-arm/arch
#ln -s proc-armv asm-arm/proc
(2)生成Makefile包含文件include/config.mk,内容很简单,定义了四个变量
ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0
(3)生成include/config.h头文件,只有一行
#include
顶层makefile先调用各子目录的makefile,生成目标文件或者目标文件库,然后再连接所有目标文件(库)生成最终的u-boot.bin。
连接的主要目标(库)如下:
OBJS = cpu/$(CPU)/start.o
LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a \
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)
显然跟平台相关的主要是:
cpu/$(CPU)/start.o
board/$(BOARDDIR)/lib$(BOARD).a
cpu/$(CPU)/lib$(CPU).a
cpu/$(CPU)/$(SOC)/lib$(SOC).a
lib_$(ARCH)/lib$(ARCH).a
这里面的四个变量定义在include/config.mk(见上述)。其余的均与平台无关,所以考虑移植的时候也主要考虑这几个目标文件(库)对应的目录。