从链接角度分析 u-boot.bin 的构成
从运行的角度分析 u-boot.bin 前 64byte 的 relocate
relocate_vectors 的实现
#ifdef CONFIG_HAS_VBAR
// 虽然走的是这一套,但是找到的协处理器cp15的C12的实现(DDI0301H_arm1176jzfs_r0p7_trm.pdf)和下面的内容对不上
// 那就分析 #else 那条路
// 这条路 其实就是 架构实现(ARM1176) 对(#else那条路) 做出的优化
// 后面在 DDI0301H_arm1176jzfs_r0p7_trm.pdf P254 找到了,继续分析这条路
/*
* If the ARM processor has the security extensions,
* use VBAR to relocate the exception vectors.
*/
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
#else
/*
* Copy the relocated exception vectors to the
* correct address
* CP15 c1 V bit gives us the location of the vectors:
* 0x00000000 or 0xFFFF0000.
*/
// r0 = gd->relocaddr
// gd->relocaddr 起始的 8个32bit是 relocated exception vectors
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
// 读 cp15 Register 1:控制寄存器 ,并选择 选择架构上指定的控制寄存器
// 读到 r2中
mrc p15, 0, r2, c1, c0, 0 /* V bit (bit[13]) in CP15 c1 */
// bit[13]
//该位用于选择异常向量的位置:
// 0=选择的正常异常向量(地址范围0x00000000-0x0000001C)
// 1=选择的高异常向量(地址范围0xFFFF0000-0xFFFF001C)。
//一个实现可以提供一个输入信号来确定复位后该位的状态。
// 选择目标地址
ands r2, r2, #(1 << 13)
ldreq r1, =0x00000000 /* If V=0 */
ldrne r1, =0xFFFF0000 /* If V=1 */
// 从 gd->relocaddr 拷贝到 0x00000000,拷贝了8个32bit
ldmia r0!, {r2-r8,r10}
stmia r1!, {r2-r8,r10}
// 又拷贝了8个32bit
ldmia r0!, {r2-r8,r10}
stmia r1!, {r2-r8,r10}
#endif
gd->relocaddr 的 16个32bit 是什么
b reset // 占用 1个 32bit
ldr pc, _undefined_instruction // 占用 1个32bit
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 // 占用1个32bit
_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 // 占用1个32bit
0x00000000 在 芯片 memory map 的什么位置 // 0xFFFF0000 不存在于 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 在哪里? // TODO
arch/arm/lib/vectors.S
.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
u-boot.lds
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*)
}
arch/arm/lib/sections.c
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 // 占用1个32bit
_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
// 第一个32bit ,更改为重定位过后 undefined_instruction 的地址
// ldr pc, [pc, #20]的时候,pc中的值为重定位过后的函数的值,就不会出现问题了
以上分析的详细过程原型 请参考 https://blog.csdn.net/u011011827/article/details/115241203
上一篇:OK6410A 开发板 (三) 14 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 boot 详细解析3 relocate_code
下一篇:OK6410A 开发板 (三) 13 u-boot-2021.01 boot 解析 SPL 镜像运行部分 boot 详细解析
设计资源 培训 开发板 精华推荐
- AM30EW-240515TZ 5V 三路输出 DC/DC 转换器的典型应用
- TTL-485
- LT3724、30V60V 至 24V 75W DC/DC 转换器,具有输入 UVLO 和全时使用的板载高压稳压器
- ADA4610-1ARZ-RL 正峰值检波器运算放大器的典型应用电路
- NCP3064DFBSTGEVB:DFN-8 升压评估板
- LTC4099 的典型应用 - 具有过压保护的 I2C 控制 USB 电源管理器/充电器
- DC919A-C,LTC2205 CMOS 输出演示板,直流输入,65Msps 16 位 ADC,DC
- CH552制作的badusb
- 简易遥控红外发射器(待验证)
- 2017全国大学生电子设计竞赛-板球-源码