从链接角度分析 u-boot.bin 的构成
从运行的角度分析 u-boot.bin 前 64byte 的 relocate
#ifdef CONFIG_HAS_VBAR
ldr r0, [r9, #GD_RELOCADDR]
mcr p15, 0, r0, c12, c0, 0
#else
ldr r0, [r9, #GD_RELOCADDR]
mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #(1 << 13)
ldreq r1, =0x00000000
ldrne r1, =0xFFFF0000
ldmia r0!, {
r2-r8,r10}
stmia r1!, {
r2-r8,r10}
ldmia r0!, {
r2-r8,r10}
stmia r1!, {
r2-r8,r10}
#endif
gd->relocaddr 的 16个32bit 是什么
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
0x00000000 在 芯片 memory map 的什么位置
0x0000_0000 | 0x07FF_FFFF | 128MB | Booting Device Region by XOM Setting | Mirrored Region
按照 ok6410a 的 电路图 OM[4:0] 为 0011 , Boot device 为 RESERVED
也就是说,但是 没有连接设备,那么 0x0000 0000 在哪里?
.globl _start
.section ".vectors", "ax"
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
.globl _reset
.globl _undefined_instruction
.globl _software_interrupt
.globl _prefetch_abort
.globl _data_abort
.globl _not_used
.globl _irq
.globl _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
.word 0x0badc0de
宏汇编
bad_save_user_regs
irq_save_user_regs
irq_restore_user_regs
get_bad_stack
get_irq_stack
get_fiq_stack
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
arch/arm/cpu/arm1176/start.o (.text*)
board/samsung/ok6410a/lowlevel_init.o (.text*)
board/samsung/ok6410a/bl2_mmc_copy.o (.text*)
}
char __image_copy_start[0] __attribute__((section(".__image_copy_start")));
问题
问题:
relocate 的目标地址 0x0000 0000 在哪里?
A 还没解决的问题
relocate 之后,如果异常发生, 0x0000 0000 中的 每一个 入口指令是不是 会 地址相关?
arm-linux-gnueabi-objdump -D u-boot > u-boot.dis 之后
1.还没解决的问题
发现 b reset 反汇编 为 b 5fb00300
一旦reset异常发生,
PC = 0x00000000
此时 0x00000000 中 是 b reset 吗???
linux 和 u-boot 也一样, 0x00000000 也写入了指令
为什么 在linux管理时 reset 的时候,还是要执行 u-boot 呢?
2. 已经解决的问题
发现 ldr pc, _undefined_instruction 反汇编 为 ldr pc, [pc, #20]
看起来 b reset 在 reset异常发生时没问题
按道理来讲_undefined_instruction异常发生时,就会有问题,因为跳转的地址与pc相关
之所以没发生问题,是因为做了fixloop
对以下7个32bit做了fixloop,更改了以下7个32bit的值
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
以上分析的详细过程原型 请参考 https://blog.csdn.net/u011011827/article/details/115241203