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-spl165 $(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_BUILD3.进而分析顶层目录下的Makefile第462行,可以知道u-boot.img是通过tools/mkimage工具由u-boot.bin生成的,u-boot.bin是如何生成的就不分析了,网上资料比我好的很多。
ALL-y += $(OBJTREE)/MLO
else
ALL-y += $(obj)u-boot.img
endif
462 $(obj)u-boot.img: $(obj)u-boot.bin463 $(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至此,MLO和u-boot.img两文件是怎么生成的已经简要的分析了一下,剩下的都是网络上有很多资料,
137 $(OBJTREE)/tools/mkimage -T omapimage \
138 -a $(CONFIG_SPL_TEXT_BASE) -d $< $
而且说的比我好多了。
下面分析下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_INIT3._main 位于arch/arm/lib/crt0.S第96行
154 bl cpu_init_cp15
155 bl cpu_init_crit
156 #endif
158 bl _main
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); }