02.07.2013 Views

Uboot中start.S源码的指令级的详尽解析

Uboot中start.S源码的指令级的详尽解析

Uboot中start.S源码的指令级的详尽解析

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

“ orr r0, r0, #0x00000002 @ set bit 2 (A) Align”<br />

的作用是:<br />

(1) 设置bit[1]:<br />

“Enable Data address alignment fault checking”打开数据地址对齐的错误检查,<br />

即如果数据地址为非法(奇数?)地址,就报错。<br />

“ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache”<br />

(1) 设置bit[12]:<br />

开启指令缓存I cache。<br />

“ mcr p15, 0, r0, c1, c0, 0”<br />

mcr指令,将刚才设置的r0的值,再写入到寄存器1中。<br />

/*<br />

* before relocating, we have to setup RAM timing<br />

* because memory timing is board-dependend, you will<br />

* find a lowlevel_init.S in your board directory.<br />

*/<br />

mov ip, lr<br />

bl lowlevel_init<br />

mov lr, ip<br />

mov pc, lr<br />

#endif /* CONFIG_SKIP_LOWLEVEL_INIT */<br />

这里,其实和前面的代码:<br />

“<br />

#ifndef CONFIG_SKIP_LOWLEVEL_INIT<br />

#endif<br />

”<br />

bl cpu_init_crit<br />

是对应的,最后一行是:<br />

“mov pc, lr”<br />

是典型的子函数调用,通过将lr的值赋值给pc,实现函数调用完成后而返回的。<br />

而<br />

“bl lowlevel_init”<br />

前面的一行:<br />

“mov ip, lr”<br />

意思是将lr的值给ip,即指令指针r12,此处之所以要保存一下lr是因为此处是在子函数<br />

“cpu_init_crit”中,lr已经保存了待会用于返回主函数的地址,即上次调用时候的pc的<br />

值,而此处如果在子函数cpu_init_crit中继续调用其他子函数lowlevel_init,而不保存<br />

lr的话,那么调用完lowlevel_init返回来时候,就丢失了cpu_init_crit要返回的位置。<br />

说白了就是,每次你要调用函数之前,你自己要确保是否已经正确保存了lr的值,要保证函数<br />

调用完毕后,也能正常返回。当然,如果你此处根本不需要返回,那么就不用去保存lr的值了。

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!