lwz r4, OR0(r3)
lis r5, ~((CONFIG_SYS_FLASH_SIZE << 4) - 1) or r4, r4, r5 stw r4, OR0(r3)
/*OR0 = OR0|0xe000_0000*/
lis r4, (CONFIG_SYS_FLASH_BASE)@h ori r4, r4, (CONFIG_SYS_FLASH_BASE)@l
stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CONFIG_SYS_FLASH_BASE */
/* Store 0x80000012 + log2(CONFIG_SYS_FLASH_SIZE) into LBLAWAR0 */ lis r4, (0x80000012)@h ori r4, r4, (0x80000012)@l
li r5, CONFIG_SYS_FLASH_SIZE
1: srawi. r5, r5, 1 /* r5 = r5 >> 1 */ addi r4, r4, 1 bne 1b
stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= Flash Size */
xor r4, r4, r4
stw r4, LBLAWBAR1(r3)
stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
blr
31
3.1.6 BAT设置 setup_bats:
/* IBAT 0 */ addis
r4, r0, CONFIG_SYS_IBAT0L@h
addis
r0, r0, 0x0000
ori r4, r4, CONFIG_SYS_IBAT0L@l addis
r3, r0, CONFIG_SYS_IBAT0U@h
ori r3, r3, CONFIG_SYS_IBAT0U@l mtspr mtspr
IBAT0L, r4 IBAT0U, r3
/* block address translation */
3.1.7 enable_addr_trans,dcache_enable,
使能地址转换:配置MSR及HID lock_ram_in_cache
3.1.8
该段代码功能为在0xe6000000处的cache处的锁定一段作为堆栈使用,便于下面C语言函数调用参数的入栈和出栈操作。
/* Allocate Initial RAM in data cache. */
lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l li
r4, ((CONFIG_SYS_INIT_RAM_END & ~31) + \\ (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
32
mtctr r4
1: dcbz r0, r3 addi r3, r3, 32 bdnz 1b
/* Lock the data cache */ mfspr
r0, HID0
ori r0, r0, HID0_DLOCK sync mtspr HID0, r0
sync blr
以及后面的设置堆栈操作: lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
li
r0, 0
stwu r0, -4(r1)
stwu r0, -4(r1)
/* let the C-code set up the rest */
/*
*/
33
/* Be careful to keep code relocatable & stack humble */ /*------------------------------------------------------*/ cpu_init_f
3.1.9
本函数在cpu_init.c中,主要设置和初始化CPU。cpu_init_f主要用到mpc8308rru.h中配置的值去初始化CPU,所以这个文件是移植过程中的重点。 cpu_init_f主要配置的寄存器如下:
1. ACR,SPCR,SCCR,SICRH,SICRL,BR,OR,BR,OR,以及GPIO的配置 2. 初始化gd全局变量
这里非常重要点为gd为向linux内核传递的参数信息,并将其保存在r2寄存器中。Gd大小为256字节。具体地址为0xe6000000+0x1000-0x100;
3.1.10 board_init_f
该函数位于board.c文件中。主要工作有:
1. 调用init_sequence数组结构中的函数,这个数组中函数N多,需要仔细看。其中
比较重要的几个: 1. get_clocks: 计算各个模块使用到的时钟。哥在调试过程中便遇到PLL计算失误导致串口不能正常打印。并将计算到的各个模块PLL保存到gd全局变量中去。 2. env_init:初始化环境变量,并将起始地址保存到gd中去。
代码很长,但是这个函数是跳转到内存中去执行的关键,需要仔细分析,代码还是贴出来:
void board_init_f (ulong bootflag) {
bd_t *bd;
34
3.init_baudrate:直接初始化串口波特率并保存到gd中去。 4. serial_init:串口初始化
ulong len, addr, addr_sp; ulong *s; gd_t *id;
init_fnc_t **init_fnc_ptr;
/* Pointer is writable since we allocated a register for it */
//gd位于0xe600_0000+0x1000-0x100位置处 gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__(\
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr) () != 0) { hang ();
}
}
/*
* Now that we have DRAM mapped and working, we can * relocate the code and continue running from DRAM. *
* Reserve memory at end of RAM for (top down in that order): * - area that won't get touched by U-Boot and Linux (optional)
* - kernel log buffer
35