思路
1.关看门狗
2.设置时钟
3.初始化sdram
4.重定位
5.执行main
.text 表示代码段
.global _start (global 表示全局标号)
关看门狗
可以调c完成disable_watch_dag 确定看门狗地址0x....
ldr r0 ,=0x... ldr 违汇编指令
mov r1,#0
str r1, [r0]
设置时钟 可以用 c clock_init()
CLKDIVN 定义位置board中
ldr r0, =0x4c00001
mov r1, #0x03 0x03 分频系数 //FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
str r1,[r0] asm 如果是c,它是标志嵌入汇编 读芯片手册,调整异步模式,根据芯片具体情况
mrc 指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断
MCR{
<opcode_1>为协处理器将执行的操作的操作码。对于CP15协处理器来说, <opcode_1>永远为0b000,当<opcode_1>不为0b000时,该指令操作结果不可预知
Rd>不能为PC,当其为PC时,指令操作结果不可预知送到得协处理器寄存器中
orr ORR指令的格式为: ORR{条件}{S} 目的寄存器,操作数1,操作数2
ORR指令用于在两个操作数上进行逻辑戒运算,并把结果放置到目的寄存器中
操作数1应该是一 个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令常用于设置操 作数1的某些位。
MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断
指令示例: ORR R0,R0,#3 ;
该指令设置R0的0、1位,其余位保持不变。
orr r0,r0,#0xd3
0xd3=1101 0111
将r0与0xd3作算数或运算,然后将结果返还给r0,即把r0的bit[7:6]和bit[4]和bit[2:0]置为1
初始化sdram 可用c语言写,memsetup
要先设置栈
sdram_config: 标号
.long 寄存器 .long 相当于数组
ldr r0,=sdram寄存器首地址
adr r1, sdram_config /* 得到当前地址 /
add r3,r0,#(134)
1:
ldr r2,r0,#4
sdr r2,[r0],#4
cmp r0,r3 比较r0,r3
bne 1b 如果不相等 1f 前面的1标
重定位 :把bootloader 本身的代码从flash复制到它的连接地址去
用c写这段,用才前要先设置栈
ldr sp, =0x3400000
bl nand_init
mov r0 ,#0
ldr r1, =[_start] 把boot copy 到 sdram 中 长度需读取连接脚本
ldr r2, = _bss_start 没有= 号为读内存指令,读_bss_start 内存 .word _bss _start 这个变量
如何引用这个变量这里的用法表示:在当前位置存放一个字,
可能有些人会觉得就是放一个字word,这个要怎么看了,
一般一个word是两个字节,跟CPU的型号有关,所以不要管word的限制,
直接理解成,在当前位置存放一个字,这个字是32位的即可
sub r2,r2,r1
bl copy_code_to_sdram 之后清零bss
bl clear_bss
执行mian
ldr lr , =halt 设置返回地址
ldr pc , =main bl main 相对跳转,根据当前指令找到偏差,再跳
假设main 能返回跳到
halt:
b halt
完成copy_code_to_sdram nor flash 不能简单地写 sd 卡 属于nand flash nand 不能像内存一样随即读取
{
src copy dsc len
}
连接文件
boot.lds
SECTIONS{
. = 0X30000000 当前地址等于多少 boot 不要放在sdram的起始位置,因为要留着放内核
.text : {(.text)} 所有代码code 段
. =ALIGN(4) 用于代码对齐,使当前地址取整
.rodata :{(.rodata)} 所有代码只读数据段
.data : {(.data)} 所有代码数据段
__bss_start = .;
.bass : {(.bss*)} 所有bss数据段 当前初始值为0的数据,给他们统一数据地址,避免冗余的0
__bss_end = .;
}
计算boot 文件大小 就是 __bass_start - start
claen_bss{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for (: p <&_bss_end;p++)
*p = 0;
}
nand_init {
}