拿到PandBoardES已经有两个星期了,前几天分析了一下TI的X-Loader程序,把它给记录下来,以供以后参考。如果哪里有问题,希望大家能够指出来。在pandaboard.org上已经描述的很清楚,可以前去仔细阅读下:
上图就是pandaboard.org上的X-Loader执行流程,下面将从源码来一步步分析:
1.下载源码:
git clone git://git.omapzoom.org/repo/x-loader.git cd x-loader git checkout remotes/origin/omap4_dev //这步可能有问题
2.设置目标板为omap4,并编译生成MLO,前提得先安装好交叉编译:
make omap44XXtablet_config make ift或
make CROSS_COMPILE=arm-none-linux-gnueabi- omap44XXtablet_config make CROSS_COMPILE=arm-none-linux-gnueabi- ift3.编译成功生成MLO文件
4.先来分析下Makefile,大概了解下执行流程, 95行:
ift: $(ALL) x-load.bin.ift
91行;
ALL = x-load.bin System.map97行
x-load.bin.ift: signGP System.map x-load.bin TEXT_BASE=`grep -w _start System.map|cut -d ' ' -f1` ./signGP x-load.bin $(TEXT_BASE) cp x-load.bin.ift MLO
123行
signGP: scripts/signGP.c gcc -O3 -o signGP $<
则可以看出来,MLO是通过signGP工具从x-loader.bin生成x-load.bin.ift,然后重新备份名为MLO的,而signGP工具则在scripts脚本下,源码为signGP.c文件,通过gcc编译得来。signGP工具在x-loader.bin上添加了写头信息,这个可以参考OMAP4460 TRM.PDF。x-load.bin则是整个Makefile的all了,这个就不去分析了,感觉整体工程跟uboot的差不多。
5.分析MLO代码执行流程
分析 /xloader/cpu/omap4/x-loader.lds 得知,首先执行/cpu/omap4/start.S文件
SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/omap4/start.o (.text) *(.text) } ...... }
//cpu/omap4/start.S 98行 reset: /* Store the boot reason/device in scratchpad */ ldr r4, scratchpad ldr r5, [r0, #0x8] /* r5 <- value of boot device */ bic r5, r5, #0xFFFFFF00 @ clear bits other than first byte*/ str r5, [r4]
R0寄存器内容是什么?可以参考omap4460 TRM.PDF第27.4.8.4章节,我的文档是OMAP4460_ES1.x_PUBLIC_TRM_vV.pdf,这里面有个小小的错误,稍微细心点就能发现,呵呵~。上面这段程序是把omap4460启动方式给保存在0x4A326000处。
// cpu/omap4/start.S 139行 bl cpu_init_crit // cpu/ompa4/start.S +191 bl lowlevel_init // cpu/omap4/platform.S +36 bl s_init // cpu/omap4/cpu.c然后执行_start_armboot函数
ldr pc, _start_armboot /* jump to C code */ _start_armboot: .word start_armboot // lib/board.c
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } }
switch (get_boot_device()) { case 0x05: strcpy(boot_dev_name, "MMC/SD1"); #if defined(CONFIG_MMC) if (mmc_read_bootloader(0) != 0) goto error; #endif break; }
#define CFG_LOADADDR 0x80e80000 unsigned long offset = CFG_LOADADDR; mmc_read_bootloader(0) { ret = mmc_init(dev); if (fat_boot()) { size = file_fat_read("u-boot.bin", (unsigned char *)offset, 0); } else { mmc_read(dev, 0x200, (unsigned char *)CFG_LOADADDR, 0x00060000); }
}
((init_fnc_t *)CFG_LOADADDR)();