韦东山uboot_内核_根文件系统学习笔记2.1.1-第002课_从0写bootloader_更深刻理解bootloader-第001节_自己写bootloader之编写第1阶段

1、准备C语言执行环境

(1)关于栈空间的设置:
Stack:即SP寄存器,它是向下增长的,可以设置SP指针指向内存的最高地址。
执行C语言函数之前必须设置栈空间(即所谓的“准备C语言执行环境”)。
(2)关于清除bss段
由于bss段默认为0,所以真正使用前需要手动清零!
_bss_start和_bss_end链接地址定义位于链接脚本里面。
所以C语言引用需要extern或者汇编语言引用需要import

//注意!_bss_start的地址才是我们想要的!即
&_bss_start
&_bss_end
//而不是
_bss_start
_bss_end

2、汇编语言常用法

以下两端代码目的均为赋值某个寄存器

//C语言代码
#define MPLLCON		0x4C000004	/* R/W, MPLL configuration register */
#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
*MPLLCON=S3C2440_MPLL_400MHZ;
//汇编代码
#define MPLLCON		0x4C000004	/* R/W, MPLL configuration register */
#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
ldr r0,=MPLLCON
ldr r1,=S3C2440_MPLL_400MHZ
str r1,[r0]

那么功能再复杂一点,我们赋值某一串寄存器为某一串的值呢?

#define MPLLCON		0x48000000	/* SDRAM configuration register */
1:
	ldr r0,=MPLLCON
	add r3,r0,#(7*4)									//r0=终止地址
	
	adr r1,SDRAM_config							//伪指令,得到SDRAM_config标号的当前地址
	ldr r2,[r1],#4											//r1地址的值给r2,然后r1+4
	str r2,[r0],#4											//r2的值给r0地址,然后r0+4
	cmp r0,r3
	bne 1b													//不相等,则跳转回标号1.b表示back;f表示forward

SDRAM_config://寄存器的值
	.long	0x00000001							//汇编语言中.long表示四个字节类型
	.long	0x00000002
	.long	0x00000003
	.long	0x00000004
	.long	0x00000005	
	.long	0x00000006	
	.long	0x00000007	

3、关于重定位

把可执行程序从一个位置复制到另一个位置的过程叫做重定位。
为什么重定位:CPU内部初始boot程序加载代码长度有限,需要继续复制代码到内存中。

4、关于绝对跳转和相对跳转

BL main 为相对跳转指令,与位置无关代码。根据当前指令,找到main函数的偏差值跳转过去。所以,若main距离比较远,则无法跳转
LDR PC,=main 为绝对跳转指令,与位置有关代码。

刚刚设置了跳转执行函数main,假设能返回呢,返回地址如何设置?
ldr lr,=halt

5、如何判断NOR启动/NAND启动

是否可以向地址随意写数据

6、汇编语言中嵌入C语言

例如调用copy_code_to_sdram(int src,int dest,int len)
参数如何调用的呢?
r0寄存器表示参数0,即src;
r1寄存器表示参数1,即dest。这里是链接地址,链接地址的标号为_start
r2…

mov r0,#0
ldr r1,=_start;		//程序起始标号,即链接的起始地址,即0x33f80000
 
 ldr r2,_bss_start //计算程序长度:_bss_start-.0x33f80000,
 sub r2,r2,r1

uboot程序长度如何确定?链接脚本可以计算
ldr r2,_bss_start //计算程序长度:_bss_start-.0x33f80000,
sub r2,r2,r1
因为_bss_start之后的地址存放的值默认为0,无需作为实际程序存储进内存啦。
但是CPU自己并不会清除内存,还是需要boot程序清零对应存储区域。
所以我们还是需要clear_bss函数。

7、链接脚本

SECTIONS{
	.=0x33f80000					//链接的起始地址,由于读出内核以后会放在下面,所以uboot代码放在最上面
	.text:{*(.text)}					//*所有文件;.text代码段
	.=ALIGN(4)						//4字节对齐
	.rodata:{*(.rodata)}			//所有文件的只读数据段,不可改变的数据
	
	.data:{*(.data)}					//全局已初始化变量
	_bss_start= .;					//定义这个的目的是 程序中会使用_bss_start变量
	.bss:{*(.bss)}					//BSS段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0。
	_bss_end= .;
}

8、汇编语言中的变量定义

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start												//定义了变量_bss_start
_bss_start:														//变量_bss_start赋值为__bss_start,赋值类型为.word
	.word __bss_start

.globl _bss_end
_bss_end:
	.word _end

.globl FREE_RAM_END
FREE_RAM_END:
	.word	0x0badc0de

.globl FREE_RAM_SIZE
FREE_RAM_SIZE:
	.word	0x0badc0de

.globl PreLoadedONRAM
PreLoadedONRAM:
	.word	0

9、关于NandFlash

位翻转:工艺决定,每个page中有OOB(out of bank)。相当于ECC校验位,可以根据ECC码反算出错误位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值