网址:http://blog.csdn.net/evenness/article/details/7395535
U-Boot的源码是通过GCC和Makefile组织编译的。顶层目录下的Makefile首先可以设置开发板的定义,然后递归地调用各级子目录下的Makefile,最后把编译过的程序链接成U-Boot映像。 1.顶层目录下的Makefile它负责U-Boot整体配置编译。按照配置的顺序阅读其中关键的几行。 每一种开发板在Makefile都需要有板子配置的定义。例如smdk2410开发板的定义如下。 smdk2410_config : unconfig @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0 执行配置U-Boot的命令make smdk2410_config,通过./mkconfig脚本生成include/config. ARCH = arm CPU = arm920t BOARD = smdk2410 SOC = s3c24x0 上面的include/config.mk文件定义了ARCH、CPU、BOARD、SOC这些变量。这样硬件平台依赖的目录文件可以根据这些定义来确定。SMDK2410平台相关目录如下。 board/smdk2410/ cpu/arm920t/ cpu/arm920t/s3c24x0/ lib_arm/ include/asm-arm/ include/configs/smdk2410.h 再回到顶层目录的Makefile文件开始的部分,其中下列几行包含了这些变量的定义。 # load ARCH, BOARD, and CPU configuration include include/config.mk export ARCH CPU BOARD VENDOR SOC Makefile的编译选项和规则在顶层目录的config.mk文件中定义。各种体系结构通用的规则直接在这个文件中定义。通过ARCH、CPU、BOARD、SOC等变量为不同硬件平台定义不同选项。不同体系结构的规则分别包含在ppc_config.mk、arm_config.mk、mips_config.mk等文件中。 顶层目录的Makefile中还要定义交叉编译器,以及编译U-Boot所依赖的目标文件。 ifeq ($(ARCH),arm) CROSS_COMPILE = arm-Linux- //交叉编译器的前缀 #endif export CROSS_COMPILE … # U-Boot objects....order is important (i.e. start must be first) OBJS = cpu/$(CPU)/start.o //处理器相关的目标文件 … LIBS = lib_generic/libgeneric.a //定义依赖的目录,每个目录下先把目标文件连接成*.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 … 然后还有U-Boot映像编译的依赖关系。 ALL = u-boot.srec u-boot.bin System.map all: $(ALL) u-boot.srec: u-boot $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ u-boot.bin: u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ …… u-boot: depend $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT) UNDEF_SYM='$(OBJDUMP) -x $(LIBS) \ |sed -n -e 's/.*__u_boot_cmd_.*/-u\1/p'|sort|uniq`;\ $(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \ --start-group $(LIBS) $(PLATFORM_LIBS) --end-group \ -Map u-boot.map -o u-boot Makefile缺省的编译目标为all,包括u-boot.srec、u-boot.bin、System.map。u-boot.srec和u-boot.bin又依赖于U-Boot。U-Boot就是通过ld命令按照u-boot.map地址表把目标文件组装成u-boot。 其他Makefile内容就不再详细分析了,上述代码分析应该可以为阅读代码提供了一个线索。 2.开发板配置头文件除了编译过程Makefile以外,还要在程序中为开发板定义配置选项或者参数。这个头文件是include/configs/<board_name>.h。<board_name>用相应的BOARD定义代替。 这个头文件中主要定义了两类变量。 一类是选项,前缀是CONFIG_,用来选择处理器、设备接口、命令、属性等。例如: #define CONFIG_ARM920T 1 #define CONFIG_DRIVER_CS8900 1 另一类是参数,前缀是CFG_,用来定义总线频率、串口波特率、Flash地址等参数。例如: #define CFG_FLASH_BASE 0x00000000 #define CFG_PROMPT "=>" 3.编译结果根据对Makefile的分析,编译分为2步。第1步配置,例如:make smdk2410_config;第2步编译,执行make就可以了。 编译完成后,可以得到U-Boot各种格式的映像文件和符号表,如表6.3所示。 表6.3 U-Boot编译生成的映像文件
U-Boot的3种映像格式都可以烧写到Flash中,但需要看加载器能否识别这些格式。一般u-boot.bin最为常用,直接按照二进制格式下载,并且按照绝对地址烧写到Flash中就可以了。U-Boot和u-boot.srec格式映像都自带定位信息。 4.U-Boot工具在tools目录下还有些U-Boot的工具。这些工具有的也经常用到。表6.4说明了几种工具的用途。 表6.4 U-Boot的工具
这些工具都有源代码,可以参考改写其他工具。其中mkimage是很常用的一个工具,Linux内核映像和ramdisk文件系统映像都可以转换成U-Boot的格式。 |