TQ2440之uboot---6.start.S中relocate部分分析,adr與ldr區(qū)別
在u-boot的start.S中有這么一段
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 duringdebug */
beq clear_bss
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /*r2 <- size of armboot */
bl CopyCode2Ram /*r0: source, r1: dest, r2: size */
clear_bss:
…….
比較r0和r1,如果不相等就把代碼從flash中copy到ram中去。但問(wèn)題是單從adr和ldr這兩條指令上怎么就能判斷出r0和r1不相等呢?
既匯編搞不定那就反匯編了,匯編以上代碼可以看出這兩個(gè)指令有不同之處
33d800b0 :
33d800b0:e24f00b8 sub r0, pc, #184 ; 0xb8
33d800b4:e51f107c ldr r1, [pc, #-124] ;33d80040 <_text_base>
33d800b8:e1500001 cmp r0, r1
33d800bc:0a000003 beq 33d800d0
adr r0, _start ==> 33d800b0: e24f00b8 sub r0, pc, #184 ; 0xb8
取pc-184處的標(biāo)號(hào)的地址,并把這個(gè)地址賦給r0,而_start是隨著加載地址的不同而變化的,所以r0是變化的。當(dāng)從nandflash運(yùn)行時(shí),實(shí)際上是在sram的0x0地址運(yùn)行,_start的地址是0x0;而從0x33d80000處運(yùn)行時(shí),此時(shí)_start的值是0x33d80000。
ldr r1, _TEXT_BASE ==>800b4: e51f107cldr r1, [pc, #-124]
字面意思是要取[pc, #-124]地址中的值,也就是要取_TEXT_BASE這個(gè)地址中的值,無(wú)論如何鏈接_TEXT_BASE的地址會(huì)變,但是_TEXT_BASE地址處的值TEXT_BASE不變。這條指令就是把_TEXT_BASE的值也就是.word TEXT_BASE賦給r1,既r1=TEXT_BASE=0x33d80000。這條指令跟程序跑在什么位置沒(méi)有關(guān)系,只要定義了TEXT_BASE,那么此處r1=TEXT_BASE.