DemonMaster

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

思路
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{} p15, 0, , , {,<opcode_2>}
<opcode_1>为协处理器将执行的操作的操作码。对于CP15协处理器来说, <opcode_1>永远为0b000,当<opcode_1>不为0b000时,该指令操作结果不可预知
作为元寄存器的ARM寄存器,其值被传<
Rd>不能为PC,当其为PC时,指令操作结果不可预知送到得协处理器寄存器中
作为目标寄存器的协处理器寄存器,其编号可能为C0,C1....C15。 附加的目标寄存器或者原操作数寄存器,用于区分同一个编号的不同物理寄存器。当指令中不需要提供附加信息时,将C0指定为,否则指令操作结果不可预知。 <opcode_2>提供附加信息,用于区别同一个编号的不同物理寄存器。当指令中指定附加信息时,省略<opcode_2>或者将其指定为0,否则指令操作结果不可预知
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,#(13
4)
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 {

}

posted on 2019-11-15 20:37  专注的长尾狸猫  阅读(217)  评论(0编辑  收藏  举报