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

从链接角度分析 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 的 1632bit 是什么

 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
			对以下732bit做了fixloop,更改了以下732bit的值
			_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

猜你喜欢

转载自blog.csdn.net/u011011827/article/details/115238661