OK6410A 开发板 (三) 13 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 boot 详细解析2 relocate_vectors

发布者:WanderlustHeart最新更新时间:2022-09-22 来源: csdn关键字:OK6410A  开发板  u-boot 手机看文章 扫描二维码
随时随地手机看文章

从链接角度分析 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  开发板  u-boot 引用地址:OK6410A 开发板 (三) 13 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 boot 详细解析2 relocate_vectors

上一篇:OK6410A 开发板 (三) 14 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 boot 详细解析3 relocate_code
下一篇:OK6410A 开发板 (三) 13 u-boot-2021.01 boot 解析 SPL 镜像运行部分 boot 详细解析

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved