_main ; CODE XREF: save_boot_params_ret+38↑p
.text_rest:80000FA0 MOV R0, #0x84000000
.text_rest:80000FA4 BIC R0, R0, #7 ; top
.text_rest:80000FA8 MOV SP, R0
.text_rest:80000FAC BL board_init_f_alloc_reserve
.text_rest:80000FB0 MOV SP, R0
.text_rest:80000FB4 MOV R9, R0
.text_rest:80000FB8 BL board_init_f_init_reserve
.text_rest:80000FBC MOV R0, #0 ; boot_flags
.text_rest:80000FC0 BL board_init_f
.text_rest:80000FC4 LDR R0, [R9,#0x48]
.text_rest:80000FC8 BIC R0, R0, #7
.text_rest:80000FCC MOV SP, R0
.text_rest:80000FD0 LDR R9, [R9]
.text_rest:80000FD4 SUB R9, R9, #0xD8
.text_rest:80000FD8 ADR LR, here ;获取标号here的绝对运行pc值 80000FEC
.text_rest:80000FDC LDR R0, [R9,#0x4C] ;取重定向的固定偏移量 比如10000000
.text_rest:80000FE0 ADD LR, LR, R0 ;加上
.text_rest:80000FE4 LDR R0, [R9,#0x38]
.text_rest:80000FE8 B relocate_code
.text_rest:80000FE8 ; End of function _main
.text_rest:80000FE8 这个地方要注意,上面的代码是在80000xxx位置跑的,而下面的代码却在 90000xxx 的位置跑
关键就在 relocate_code,relocate_code这个函数把从80000000开始的代码拷贝到了90000000
开始的位置,当然也包括现在描述的这个部分。并且对 LDR PC, =xxx 这样的指令做了重新偏移映射
LR在 relocate_code 之前已经计算好是 90000xxx的位置,BX LR 就跳到新地址去运行了。
.text_rest:80000FEC
.text_rest:80000FEC ; =============== S U B R O U T I N E =======================================
.text_rest:80000FEC
.text_rest:80000FEC
.text_rest:80000FEC here ; DATA XREF: _main+38↑o
.text_rest:80000FEC BL relocate_vectors
.text_rest:80000FF0 BL c_runtime_cpu_setup
.text_rest:80000FF4 LDR R0, =__rel_dyn_start
.text_rest:80000FF8 LDR R3, =__bss_end
.text_rest:80000FFC MOV R1, #0
.text_rest:80001000 SUBS R2, R3, R0
.text_rest:80001004 BL memset
.text_rest:80001008 BL coloured_LED_init
.text_rest:8000100C BL red_led_on
.text_rest:80001010 MOV R0, R9 ; new_gd
.text_rest:80001014 LDR R1, [R9,#0x38] ; dest_addr
.text_rest:80001018 LDR PC, =board_init_r
.text_rest:80001018 ; End of function here
.text_rest:80001018
.text_rest:80001018 ; ---------------------------------------------------------------------------
.text_rest:8000101C off_8000101C DCD __rel_dyn_start ; DATA XREF: here+8↑r
.text_rest:80001020 off_80001020 DCD __bss_end ; DATA XREF: here+C↑r
.text_rest:80001024 off_80001024 DCD board_init_r ; DATA XREF: here+2C↑r
relocate_code ; CODE XREF: _main+48↑j
.text_rest:800014D8 LDR R1, =__image_copy_start
.text_rest:800014DC SUBS R4, R0, R1
.text_rest:800014E0 BEQ relocate_done
.text_rest:800014E4 LDR R2, =__rel_dyn_start
.text_rest:800014E8
.text_rest:800014E8 copy_loop ; CODE XREF: relocate_code+1C↓j
.text_rest:800014E8 LDM R1!, {R10,R11}
.text_rest:800014EC STM R0!, {R10,R11}
.text_rest:800014F0 CMP R1, R2
.text_rest:800014F4 BCC copy_loop
.text_rest:800014F8 LDR R2, =__rel_dyn_start
.text_rest:800014FC LDR R3, =(seqNumFlag+0x38DC)
.text_rest:80001500
.text_rest:80001500 fixloop ; CODE XREF: relocate_code+4C↓j
.text_rest:80001500 LDM R2!, {R0,R1}
.text_rest:80001504 AND R1, R1, #0xFF
.text_rest:80001508 CMP R1, #0x17
.text_rest:8000150C BNE fixnext
.text_rest:80001510 ADD R0, R0, R4
.text_rest:80001514 LDR R1, [R0]
.text_rest:80001518 ADD R1, R1, R4
.text_rest:8000151C STR R1, [R0]
.text_rest:80001520
.text_rest:80001520 fixnext ; CODE XREF: relocate_code+34↑j
.text_rest:80001520 CMP R2, R3
.text_rest:80001524 BCC fixloop
.text_rest:80001528
.text_rest:80001528 relocate_done ; CODE XREF: relocate_code+8↑j
.text_rest:80001528 BX LR
.text_rest:80001528 ; End of function relocate_code