韦东山uboot学习笔记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码反算出错误位。