拿到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- ift
3.編譯成功生成MLO文件
4.先來分析下Makefile,大概瞭解下執行流程, 95行:
ift: $(ALL) x-load.bin.ift
91行;
ALL = x-load.bin System.map
97行
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
在start_armboot函數裏,首先初始化一些信息
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
獲得啓動模式,我們這裏是MMC啓動,則執行mmc_read_bootloader函數
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;
}
在mmc_read_bootloader裏,如果是FAT啓動,則尋找u-boot.bin文件,加載到內存0x80e80000處,
如果是RAW處開始讀,則從0x200處開始,讀0x00060000到0x80e80000處。
#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);
}
}
拷貝完uboot.bin之後,執行下面語句,則把程序跳轉到uboot裏開始執行
((init_fnc_t *)CFG_LOADADDR)();
執行到這裏後,在也回不了MLO來了,MLO程序大體執行流程就是這樣的,我試了下,能夠拷貝uboot.bin,程序能夠跳過去,但是uboot.bin執行一半就死掉了,具體原因以後在來分析。後面會寫出詳細的MLO程序主要流程代碼分析的。