我用的是u-boot1.3.2,开发板是s3c2440,所以用的是cpu/arm920t/start.s,如果谁看过这个文件,请帮忙回答下以下几个问题:
1. 127行有如下几句话,请问一下这个0x0是RAM地址还是FLASH地址?
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
这个东西目的好像是为了把中断向量表复制过去,但是就是不知道要复制去哪里,还有就是中断向量表不是只有8*4的吗?为什么这里是16*4??
2. 程序从第178行的bl cpu_init_crit返回后,进入如下这段代码:
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot
_start_armboot: .word start_armboot
现在问题是这样的:
a.这个代码是什么作用?
b. _TEXT_BASE只是个变量,没任何东西,怎么会和_start相等呢?
c. 进入beq stact_setup这句话在执行后,还会返回这里吗?pc值怎么处理的?如果进入了stack_setup,那等它执行完后去执行哪一句?
d. _start_armboot: .word start_armboot这句话是定义一个变量,那请问它是如何与start_armboot关联起来的?如何转去执行start_armboot.c这个文件?
原来精研过这个东西,不过现在不太清楚了,我可以提供一些建议,一是从网上下周立功的说明,我原来基本就是在这个基础上看的,相当清楚.二是找周立功的开发板儿上会带.
引用: 引用 1 楼 fpcc 的回复:
原来精研过这个东西,不过现在不太清楚了,我可以提供一些建议,一是从网上下周立功的说明,我原来基本就是在这个基础上看的,相当清楚.二是找周立功的开发板儿上会带.
我也有开发板和全套说明啊,这个U-boot不是它带的,而是我从网上下的源码,需要自己移植过的,只是这个源码按理说start.s里面只需要改一些寄存器之类的,像我上述这些东西应该是通用的啊。
引用: 引用 5 楼 thesaviour 的回复:
此时还是物理地址,应该是bootrom的地址。
这个0X0还是物理地址?那它干嘛要做这个拷贝的过程啊?bootloader烧进去后不是flash里就有中断向量表了吗?怎么还进行一次拷贝,这不是多此一举吗?
请问一下这个0x0是RAM地址还是FLASH地址?
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
这个东西目的好像是为了把中断向量表复制过去,但是就是不知道要复制去哪里,还有就是中断向量表不是只有8*4的吗?为什么这里是16*4??
我也来说两句,这个0x0肯定不是nandflash地址(不知道你板子上是nor还是nand),有的ARM芯片内部自带有
SRAM(4K的8K的都有),且根据配置有的是从整个内存的0地址开始的,你这个0x0估计就是ARM片内的SRAM地址地址,nandflash里面通过烧录确实已经把中断向量表烧到nandflash里面了,但是运行的时候需要把它们加载到SRAM中来。
或者说,你这个0地址是已经映射过的,可能代表的是片外SDRAM?
你参考一下看看
d. _start_armboot: .word start_armboot这句话是定义一个变量,那请问它是如何与start_armboot关联起来的?如何转去执行start_armboot.c这个文件?
定义一个变量在这里就相当于声明一个4BYTES的内存空间,且在这空间里放上start_armboot()这个函数的的地址。把它付给PC,就相当于强制执行这个start_armboot()程序了
b. _TEXT_BASE只是个变量,没任何东西,怎么会和_start相等呢?
_TEXT_BASE是你在编译器的分散加载文件中指定的吧,好像就是比较代码的运行域和加载域是否相等,如果不相等则需要拷贝了
跟vivi的差不多。
引用: 引用 10 楼 ialwaysgo 的回复:
b. _TEXT_BASE只是个变量,没任何东西,怎么会和_start相等呢?
_TEXT_BASE是你在编译器的分散加载文件中指定的吧,好像就是比较代码的运行域和加载域是否相等,如果不相等则需要拷贝了
跟vivi的差不多。
前面应该有一句:
_TEXT_BASE: .word TEXT_BASE
其中TEXT_BASE定义在board目录下相应的config.mk中
所以这边我猜想其实是检查这段代码执行的位置。因为最终代码要在RAM里执行,所以如果之前的_start是定向到falsh的,那就是0x0,就把代码copy到RAM的地址TEXT_BASE开始的空间里去,然后执行。
引用: 引用 8 楼 ialwaysgo 的回复:
请问一下这个0x0是RAM地址还是FLASH地址?
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
这个东西目的好像是为了把中断向量表复制过去,但是就是不知道要复制去哪里,还有就是中断向量表不是只有8*4的……
我也比较同意你的看法,只是我觉得机器在刚启动的时候会自动的通过硬件把bootloader的前4K拷贝进入你说的片内RAM,但是既然已经拷贝进入,为什么还要加载进去呢?它已经在RAM里了啊。呵呵,比较奇怪
引用: 引用 11 楼 tankdin 的回复:
引用 10 楼 ialwaysgo 的回复:
b. _TEXT_BASE只是个变量,没任何东西,怎么会和_start相等呢?
_TEXT_BASE是你在编译器的分散加载文件中指定的吧,好像就是比较代码的运行域和加载域是否相等,如果不相等则需要拷贝了
跟vivi的差不多。
前面应该有一句:
_TEXT_BASE: .word TEXT_BASE
其中TEXT_BASE定义在b……
这里我后来仔细在看,就是看不明白何时才会有相等的情况出现?不管是在RAM还是在FLASH,我感觉始终不可能出现CMPEQ这句话被执行啊,而根据代码,其实它的意思是当CMPEQ被执行时,说明是从RAM启动,也就是在类似与休眠或者挂起的情况下,再次被唤醒。所以它会跳过拷贝代码这个过程。但是挂起后,TEXT_BASE和_start难道是相等的吗?各自应该是多少地址?
http://fpcfjf.blog.163.com/blog/static/554697932009314114647642/
或者我的博客可以有些帮助.
TEXT_BASE是在链接时就确定的。
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
上面这段的r0和r1是会相等的。
因为r0存放的是_start运行处的地址,当代码段被拷贝到TEXT_BASE并执行以后,_start和_TEXT_BASE应该就会cmpeq。这时候就是我之前说的,开始在RAM中执行了。
引用: 引用 15 楼 tankdin 的回复:
TEXT_BASE是在链接时就确定的。
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc d……
恩,明白了。对具体运行的知识还是不够啊,呵呵。悲剧啊,能加个你的qq吗?我的是215587754
回#13:
http://student.eeworld.net/space.php?uid=91306&do=blog&id=6811
看一下这个。