u-boot-2013.01完美的支持了pandaboardES开发板,其能够生成MLO和u-boot.img文件,现在来分析一下这两个文件是怎么生成的。
1.打开顶层目录下的Makefile,找到424行all,all目标依赖于$(ALL-y),
424 all: $(ALL-y) $(SUBDIR_EXAMPLES)继续向上需找,在411行得知需要依赖于CONFIG_SPL宏,
411 ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin该宏在include/configs/Omap4_common.h中234行定义
233 /* Defines for SPL */
234 #define CONFIG_SPL打开分析spl/Makefile,在第164行跟踪u-boot-spl.bin如何生成
164 $(obj)u-boot-spl.bin: $(obj)u-boot-spl 165 $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@在spl/Makefile第18行得知,导出CONFIG_SPL_BUILD:=y宏
18 CONFIG_SPL_BUILD := y
19 export CONFIG_SPL_BUILD2.打开arch/arm/cpu/armv7/omap4/config.mk,可以得知,定义了CONFIG_SPL_BUILD宏生成ALL-y += $(OBJTREE)/MLO,而没有定义CONFIG_SPL_BUILD宏,则生成u-boot.img
ifdef CONFIG_SPL_BUILD ALL-y += $(OBJTREE)/MLO else ALL-y += $(obj)u-boot.img endif3.进而分析顶层目录下的Makefile第462行,可以知道u-boot.img是通过tools/mkimage工具由u-boot.bin生成的,u-boot.bin是如何生成的就不分析了,网上资料比我好的很多。
462 $(obj)u-boot.img: $(obj)u-boot.bin 463 $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \ 464 -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \ 465 -e $(CONFIG_SYS_UBOOT_START) \ 466 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \ 467 sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \ 468 -d $< $@4.进而分析spl/Makefile第136,MLO是通过tools/mkimage工具有u-boot-spl.bin生成的
136 $(OBJTREE)/MLO: $(obj)u-boot-spl.bin 137 $(OBJTREE)/tools/mkimage -T omapimage \ 138 -a $(CONFIG_SPL_TEXT_BASE) -d $< $至此,MLO和u-boot.img两文件是怎么生成的已经简要的分析了一下,剩下的都是网络上有很多资料,
下面分析下MLO的执行流程,通过上面的分析可以知道,uboot在编译的时候会导出CONFIG_SPL_BUILD := y宏
1.arch/arm/cpu/armv7/start.S 126行 reset处开始执行
126 reset:
127 bl save_boot_params //保存启动参数2.arch/arm/cpu/armv7/start.S 153行
153 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 154 bl cpu_init_cp15 155 bl cpu_init_crit 156 #endif 158 bl _main3._main 位于arch/arm/lib/crt0.S第96行
115 bl board_init_f4.board_init_f 位于arc/arm/lib/Spl.c第42行
52 board_init_r(NULL, 0);
5.board_init_r 位于arc/arm/lib/Spl.c第158行,在这个函数里加载uboot.img到内存里,通过跳转过去,同时通过r0把启动信息给传递过去
242 jump_to_image_no_args(&spl_image); __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); image_entry_noargs_t image_entry = (image_entry_noargs_t) spl_image->entry_point; debug("image entry point: 0x%X\n", spl_image->entry_point); /* Pass the saved boot_params from rom code */ #if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) image_entry = (image_entry_noargs_t)0x80100000; #endif u32 boot_params_ptr_addr = (u32)&boot_params_ptr; image_entry((u32 *)boot_params_ptr_addr); }