【正文】
*id, ulong dest_addr){cmd_tbl_t *cmdtp。 *//* If caches were enabled, we would have to flush them here.*//* Jump to where we39。/* delay slott1, 4t0, t2, 1baddut0, 4blet3, 0(t1)addut3, 0(t0)sw*//** t0 = source address* t1 = target address* t2 = source end address*//* 復(fù)制代碼到內(nèi)存 */1:lw /* t6 relocation offsett6, gp, t6 */sub/* gp now adjustedgp, a2gp, CFG_MONITOR_BASEaddt6, gpsubt1, a2/** Fix GOT pointer:** New GOTPTR = (old GOTPTR CFG_MONITOR_BASE) + Destination Address*//* 根據(jù)傳遞的參數(shù)計(jì)算移動(dòng)距離 */move*/move/* t2 uboot_end_datat2, 12(t3)t3, in_ramlwt0, CFG_MONITOR_BASEla */li /* Set new stack pointersp, a0relocate_coderelocate_code:moverelocate_code.ent復(fù)制代碼以上為初始化函數(shù)列表,依次運(yùn)行在初始化完成后,board_init_f 調(diào)用 relocate_code 將 UBoot 代碼從 Flash 中復(fù)制到內(nèi)存中,再?gòu)膬?nèi)存中執(zhí)行回到 cpu/mips/.globl /* NOTREACHED relocate_code() does not return */}復(fù)制代碼board_init_f 的作用為進(jìn)行內(nèi)存、時(shí)鐘、串口等設(shè)備的初始化,并為 UBoot 的運(yùn)行劃分內(nèi)存。/* On the purple board we copy the code in a special way* in order to solve flash problems*/ifdef CONFIG_PURPLEcopy_code(addr)。 = gdbaudrate。DRAM memory in bytes */bdbi_baudrateof /* size = CFG_SDRAM_BASE。省略/** Save local variables to board info struct*//* 記錄內(nèi)存基址及大小、串口波特率 */bdbi_memstart= ~(4096 1)。endif/** Now that we have DRAM mapped and working, we can* relocate the code and continue running from DRAM.*/addr = CFG_SDRAM_BASE + gdram_size。)。puts (DRAM:printf(%s\n\n,board_string)。 ++init_fnc_ptr) {if ((*init_fnc_ptr)() != 0) {hang ()。/* 依次運(yùn)行初始化函數(shù) */for (init_fnc_ptr = init_sequence。/* piler optimization barrier needed for GCC = */__asm__ __volatile__(: : :memory)。endif/* Pointer is writable since we allocated a register for it.*/gd = amp。ifdef COMPRESSED_UBOOTchar board_string[50]。uboot_end CFG_MONITOR_BASE。init_fnc_t **init_fnc_ptr。然后跳轉(zhuǎn)到 board_init_f 進(jìn)行執(zhí)行下面開(kāi)始在 C 環(huán)境中運(yùn)行文件:lib_mips/void board_init_f(ulong bootflag){gd_t gd_data, *id。 至于為什么不跳轉(zhuǎn)到 0xbf000000 + x 處運(yùn)行,是因?yàn)?AR71XX CPU 在復(fù)位時(shí),緩存可用,因此通過(guò) Kseg0 段執(zhí)行,可以加快速度。 t0, CP0_CONFIG復(fù)制代碼以上代碼前半部分通過(guò)設(shè)置 GPIO 來(lái)點(diǎn)亮路由的 LED。t0, CONF_CM_UNCACHEDmtc0 v0, 0(a1)省略/* CONFIG0 register */li v0, 0(a1)lw v1, 0(a1)lw v1, v1, v0sw v0, 0x3fdffor v1, 0(a1)li a1, AR7100_GPIO_OElw added by lsz to fix the LED issue */li/* software reboot */RVECENT(romReserved,2)省略RVECENT(romReserved,125)RVECENT(romReserved,126)RVECENT(romReserved,127)/* We hope there are no more reserved vectors!* 128 * 8 == 1024 == 0x400* so this is address R_VEC+0x400 == 0xbfc00400*/復(fù)制代碼以上代碼設(shè)置異常向量,不需要理解第一句 RVECENT(reset,0) 為一個(gè)跳轉(zhuǎn),直接轉(zhuǎn)到下面的代碼進(jìn)行運(yùn)行.align 4reset:/* set GPIO_OE/* Uboot entry point */RVECENT(reset,1)UBoot 中的起始代碼在 cpu/mips/ 中:_start:ifndef COMPRESSED_UBOOTRVECENT(reset,0)*注意:UBoot 在編譯時(shí),實(shí)際設(shè)置的基址,即啟動(dòng)地址為 KSEG0ADDR(0x1f000000),即 0x9f000000。主要的映射范圍:DDR:0~0x0fffffff (這一段直接映射物理內(nèi)存,一般通過(guò)帶緩存的 Kseg0 來(lái)訪問(wèn),以便加快速度)I/O空間:0x10000000 ~ 0x1dffffff (這一段直接控制硬件,必須通過(guò) Kseg1 來(lái)訪問(wèn))SPI Flash 空間:0x1f000000 ~ 0x1fffffff (這一段映射閃存的前 16MB 數(shù)據(jù))AR71XX 啟動(dòng)過(guò)程CPU 上電時(shí),物理段中,SPI Flash 的前4MB 被循環(huán)映射在 0x1f000000 上,因此會(huì)被重復(fù) 4 次。AR71XX 物理段:內(nèi)存、Flash、IO寄存器等都被映射在物理段上范圍為 0~0x1fffffff,訪問(wèn)時(shí)需要通過(guò)宏 KSEG0ADD