uboot rom拷贝

uboot rom 拷贝

一、code

relocate:                /* relocate U-Boot to RAM        */
    adr    r0, _start        /* r0  = _start : current position of code   */
    ldr    r1, _TEXT_BASE        /*r1 = _TEST_BASE : test if we run from flash or RAM */
    cmp     r0, r1                  /*r0 - r1 eq jump to stack_setup,nor flash  下面的case说明是ROM*/
    beq     stack_setup

    ldr    r2, _armboot_start  /*r2 = _armboot*/
    ldr    r3, _bss_start	/*r3 = _bss_start*/
    sub    r2, r3, r2        /* r2 : size of armboot            */
    add    r2, r0, r2        /* r2 : test end address         */

copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop

二、简要说明

其中,
adr r0, _start
是取得_start行在内存(Nor Flash ROM)的实际位置,_TEXT_BASE则是RAM中的位置。
实际把plain binary格式的u-boot烧写到NOR Flash运行时,需要把Nor Flash中的
代码拷贝到RAM。当u-boot在NorFlash中运行时,adr r0,_start可以取得该行的
实际位置。

_armboot_start的值
_armboot_start:
    .word _start
此值在编译时已经决定,为0x33F80000
_bss_start的值
_bss_start:
    .word __bss_start
此值在编译时已经决定,即__bss_start的值,在link script中定义。
u-boot代码长度 = _armboot_start - _bss_start
u-boot代码末地址 = r2
ldmia : 每次取8个word
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
直到r0 > r2 ,其中ble表示 <=,即r0<=r2时循环拷贝。

三、简单的例子

test.S

.text
.global _start
_start:
    ldr r0, test
    adr r0, test
    ldr r0, =test
    ldr r0, =0x0
    ldr r0, =0x3000000
    nop
test:
    nop
    nop

test.lds

STACK_SIZE = 0X200;
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS {
    . = 0x3000;
    .text          :   { *(.text) }
    .rodata ALIGN(4) : {*(.rodata)}
    .data ALIGN(4) : { *(.data) }
    .bss ALIGN(4)  : { *(.bss)  *(COMMON) }
}

makefile

all:test_adr.S
	arm-linux-gnueabihf-gcc -c -o test_adr.o test_adr.S
	arm-linux-gnueabihf-ld -T test.lds test_adr.o -o test_adr_elf
	arm-linux-gnueabihf-objcopy -O binary -S test_adr_elf test_adr.bin
	arm-linux-gnueabihf-objdump -DS -m arm test_adr_elf >  test_adr.dis

的到的 反汇编文件

Disassembly of section .text:

00003000 <_start>:
    3000:	e59f0010 	ldr	r0, [pc, #16]	; 3018 <test>
    3004:	e28f000c 	add	r0, pc, #12
    3008:	e59f0010 	ldr	r0, [pc, #16]	; 3020 <test+0x8>
    300c:	e3a00000 	mov	r0, #0
    3010:	e3a00403 	mov	r0, #50331648	; 0x3000000
    3014:	e320f000 	nop	{0}

00003018 <test>:
    3018:	e320f000 	nop	{0}
    301c:	e320f000 	nop	{0}
    3020:	00003018 	andeq	r3, r0, r8, lsl r0

分析

  1. 先分析第一条指令ldr r0,test被编译成ldr r0, [pc, #16] ; 3018 ,
    即到当前PC+16的存储器取值,运行第一条指令时,PC其实已经是8了(流水线决定的)。
    那么16+8等于0x18,所以r0等于e320f000 ,此指令的作用就是读取test地址处存放的值。由于此处放了一条nop,即得到nop的机器码, 注意这里 r0值是一个机器码,是一个指令,一般都指令寄存器处理
  2. 第二条adr r0,test被编译成add r0, pc, #12
    这显然是依赖程序执行到此处的PC值。ADR是小范围地址读取伪指令,会将基于PC 相对偏移的地址值读取到寄存器中,此指令在3004地址,PC是3004+8=0x300c再加12,于是r0=0x3018。这个就是地址
  3. ldr r0,=test被编译成两个字,一个指令,一个文字池
    执行到这里PC=0x3008, 0x3008+8+16=0x3020,所以在0x3020地址取值,编译器在此地址处放了00003018 ,00003018 是test的值,假如在Makefile指定连接地址是0x30000000,那么编译器放在这里的就是0x30000018,可见,这个值是编译时确定的。是个地址
    最后一行andeq r3, r0, r8, lsl r0大概是编译器的机械动作,把一个数字翻译成了指令。

总结:

adr 相对偏移, 小范围, 就是取标号的地址值
ldr without =,取此标号内容,可能是指令,可能是地址;
ldr with =,就是这个标号的地址值,ldr跟带等于的立即数, 就是把此立即数当做地址值赋值给相关寄存器

四、 指令参考

adr ldr
cmp
ldmia stmia
start.S简析
start.S详细
boot spl 系列, 建议细看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
U-BootBootROM是嵌入式系统中两个不同的概念和组件。 1. U-Boot(Universal Bootloader):U-Boot是一种常用的开源引导加载程序(bootloader),用于初始化硬件并加载操作系统。它通常位于可擦写存储器(如闪存)中,是启动流程的第一个软件组件。U-Boot具有丰富的功能,包括引导选择、文件系统支持、网络功能、命令行界面等。它负责启动嵌入式系统,初始化硬件设备(如处理器、内存、外设等),并将控制权转交给操作系统。 2. BootROMBoot Read-Only Memory):BootROM是嵌入式系统中的固化存储器(通常是只读存储器),用于存储启动流程的第一段代码。它是嵌入式处理器芯片中的一部分,通常由芯片制造商提供并预先烧录到处理器内部。BootROM代表系统启动的最早阶段,包含了处理器的基本初始化代码,用于启动芯片和加载引导加载程序。BootROM通常执行一些基本的硬件初始化,并负责从外部存储器(如闪存、EEPROM等)中加载引导加载程序到内存中。 因此,U-BootBootROM都与系统启动流程相关,但是它们的作用和位置不同。BootROM位于处理器内部,是启动流程的最早阶段,负责加载引导加载程序。而U-Boot是引导加载程序的一种实现,通常存储在可擦写存储器中,并在系统启动时加载和执行,负责初始化硬件设备并将控制权转交给操作系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值