1 。u-boot程序的入口地址问题
要理解程序的入口地址,自然想到的是连接文件,首先看看开发板相对于某个开发板的连接文件
"/board/你的开发板
/u-boot.lds",看一个
2410的例子:
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
(1) 从
ENTRY(_start)可以看出
u-boot的入口函数是
_start,这个没错
(2) 从
. = 0x00000000也许可以看出
_start的地址是
0x00000000,事实并不是这样的,这里的
0x00000000没效,在连接的时候最终会被
TETX_BASE所代替的,具体请参考
u-boot根目录下的
config.mk.
(3) 网上很多说法是
_start=TEXT_BASE,我想这种说法也是正确的,但没有说具体原因。
本人的理解是这样的,
TEXT_BASE表示
text段的起始地址,而从
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}
看,放在
text段的第一个文件就是
start.c编译后的内容,而
start.c中的第一个函数就是
_start,所以
_start应该是放在
text段的起始位置,因此说
_start=TEXT_BASE也不为过。
2. U-BOOT是怎样从4Ksteppingstone跳到RAM中执行的,关键在于:
ldr pc, _start_armboot
_start_armboot: .word start_armboot
这两条语句,
ldr pc, _start_armboot指令把
_start_armboot这个标签的地方存放的内容
(也即是
start_armboot)移到
PC寄存器里面,
start_armboot是一个函数地址,在编译的时候给分配了一个绝对地址,所以上面语句实际上是完成了一个绝对地址的跳转。而我一直不明白的为什么在
start.S里面有很多
BL,B跳转语句都没有跳出
4Ksteppingstone,原因是他们都是相对于
PC的便宜的跳转,而不是绝对地址的跳转。还有要补充一下
LDR,MOV,LDR伪指令的区别。
LDR R0,0x12345678 //把地址
0x12345678存放的内容放到
R0里面
MOV R0,#x //把立即数
x放到
R0里面,
x必须是一个
8 bits的数移到偶数次得到的数。
LDR R0,=0x12345678 //把立即数
0x12345678放到
R0里面