uboot-重定位、nand norflash启动

##nand flash启动

cpu无法给nand flash发送指令,因此无法从nand flash中取指令的。那么上电后,为啥依然可以从nand flash中启动uboot呢?

1.硬件会自动将nand flash的代码前4K拷贝到SRAM(片内内存,steppintstone)中。CPU从SRAM的0地址中执行代码。如果uboot的代码大于4K怎么办?uboot中前4K的代码需要初始化nand flash,SDRAM,并将nand flash中整个uboot程序读出来,拷贝到SDRAM的中。这个过程其实就是代码重定位。

##nor flash启动

nor flash是内存类结构,可以直接向内存一样访问的,但是无法像内存一样写。因此,当从nor flash启动时,CPU会从nor flash的0地址开始执行指令,但是注意指令中只能读取变量,而无法修改变量的值。所以,也需要把全局变量和静态变量重定位到sdram中。

##程序各个代码段

.text 代码段
.data 数据段 (初始化的全局变量或者静态局部变量)
rodata 只读数据段(const全局变量)
bss段 (初始值为0,未初始化的全局变量)
commen 注释
其中bss段和commen 注释不保存在bin文件中。

##关于lds的实验

实验代码来自于韦东山的嵌入式课本源码: hardware\i2c

链接脚本

SECTIONS {
. = 0x00000000;
.init : AT(0){ head.o init.o nand.o}
. = 0x30000000;
.text : AT(4096) { *(.text) }
.rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {*(.rodata*)} 
.data ALIGN(4)   : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)) { *(.data) }
__bss_start = .;
.bss ALIGN(4)  : { *(.bss)  *(COMMON) }
__bss_end = .;
}

反汇编文件:

i2c_elf:     file format elf32-littlearm

Disassembly of section .init:

00000000 <_start>:
   0:	ea000006 	b	20 <Reset>

00000004 <HandleUndef>:
   4:	eafffffe 	b	4 <HandleUndef>

00000008 <HandleSWI>:
   8:	eafffffe 	b	8 <HandleSWI>

0000000c <HandlePrefetchAbort>:
   c:	eafffffe 	b	c <HandlePrefetchAbort>

00000010 <HandleDataAbort>:

…………    
5a0:	00696261 	.word	0x00696261
5a4:	00000501 	.word	0x00000501
5a8:	00000000 	.word	0x00000000
Disassembly of section .text:     #代码段的开始,如lds脚本,开始地址为30000000。之前存放的是初始化段,包含head.o init.o nand.o 三个文件的代码

30000000 <init_irq>:
30000000:	e59f2030 	ldr	r2, [pc, #48]	; 30000038 <init_irq+0x38>
30000004:	e59f1030 	ldr	r1, [pc, #48]	; 3000003c <init_irq+0x3c>
30000008:	e28230c8 	add	r3, r2, #200	; 0xc8
3000000c:	e4821004 	str	r1, [r2], #4
30000010:	e1520003 	cmp	r2, r3
30000014:	1afffffc 	bne	3000000c <init_irq+0xc>
30000018:	e59f3020 	ldr	r3, [pc, #32]	; 30000040 <init_irq+0x40>
3000001c:	e3a0144a 	mov	r1, #1241513984	; 0x4a000000
30000020:	e502305c 	str	r3, [r2, #-92]

##lds文件解析

SECTIONS {
    . = 0x00000000;
    .init : AT(0){ head.o init.o nand.o}
    . = 0x40000000;    ##表示之后的各个段汇编代码的绝对路径。指令中绝对跳转使用的就是这个地址。对应于运行地址、链接地址。
    .text : AT(2048) { *(.text) }   ##AT表示这个段放在bin文件偏移2048的位置。可以用ue打开文件,在2048地址处查看到对应的机器码。对应于加载地址。
    .rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {*(.rodata*)} 
    .data ALIGN(4)   : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)) { *(.data) }
    __bss_start = .;
    .bss ALIGN(4)  : { *(.bss)  *(COMMON) }
    __bss_end = .;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值