1. x-loader執行流程分析

        拿到PandBoardES已經有兩個星期了,前幾天分析了一下TI的X-Loader程序,把它給記錄下來,以供以後參考。如果哪裏有問題,希望大家能夠指出來。在pandaboard.org上已經描述的很清楚,可以前去仔細閱讀下:

Bootloaders xloader cropped.jpg

        上圖就是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_init_crit,初始化CPU和板子的一些信息,下面是代碼的執行流程

	// 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程序主要流程代碼分析的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章