国嵌上学期笔记-自己实现bootloader-第一节

一、思路

1、分析异常向量表


arm920T有7个异常。

Reset重启时产生该异常。

Undefined instructions未定义指令异常。

SWI软中断。

Prefetch Aboart预取指令失败产生。

Data Abort预取数据失败。

IRQ中断。

FIQ快速中断。

发生异常的时候,会自动跳转到固定的地址来执行,这个地址叫异常向量。表中每个异常对应两个地址,默认前面的,如果要用后面的,需要配置CP15协处理器。

注意:第5和6之间有个间隔,写代码时要插入一个无关指令占位。

用到的指令:ldr指令把内存单元地址里面的内容装载。

arm-linux-ld -Tgboot.lds -o gboot.elf $^                       -T加上链接器脚本的文件名。

arm-linux-objcopy -O binary gboot.elf gboot.bin           转换成二进制

bootloader工作在SVC模式,可以使用更多的指令,有很高的权限。

2、设置为SVC模式

设置为SVC模式:通过程序状态寄存器CPSR(补充:程序状态寄存器有6个CPSR和5个SPSR)。

相关指令:bic清零,orr位或指令置一,msr,mrs指令。程序状态寄存器不能直接修改,放到通用寄存器修改,之后再写回去。


设置0到4可以改变工作模式。后五位和0x13位或。uboot里面是设置0xd3,改变了I和F,屏蔽了中断。


3、关闭看门狗

看门狗作用:例如雪山上的基站,如果死机,自动重启,不需要人去操作。实质是硬件定时器,在计时结束之前,要重新设置定时器(喂狗),到时间还没有喂狗,就重启。

由于bootloader运行的简单程序,不需要看门狗,喂狗太麻烦,所以关闭。

相关指令:mov只能在寄存器之间传递数据,不能操作内存。

STR    Rd, [Rbase]          存储 Rd 到 Rbase 所包含的有效地址


4、关闭中断

设置SVC模式的时候已经顺便关闭了I和F的中断。

另外还需要设置中断屏蔽寄存器,屏蔽中断。

MASK屏蔽寄存器。

指令:mvn把操作数取反,在存到某个寄存器



5、关闭MMU和Catch

看芯片手册。

MMU:内存管理单元。

Catch:处理器通过Catch访问数据,主存储器要访问的数据没在Catch中,则内存中的数据会传给处理器,同时copy一份到Catch中。



MMU:如果没有MMU,则程序员必须知道有多少程序运行,占用了哪些地址,哪些地址可以用。如果随意选择,会产生冲突。

如果有64M空间,使用物理地址只能使用64M,使用的地址范围较小。引入虚拟地址,程序员可以随意写地址,经过MMU可以映射到不同的物理地址。解决地址冲突问题。访问地址空间变大,比如可以使用4G空间,MMU会映射到实际的物理地址。

如下图,ARM11之前,可以直接用虚拟地址访问。ARM11开始,虚拟地址要经过MMU映射为物理地址来访问Catch。



看内核ARM920T的手册:

找到CP15,control寄存器,下面是读写该寄存器的方法。第12位控制ICatch,第2位控制DCatch,第0位控制MMU。




还要使ICatch和DCatch的失效,指令如下,Rd代表某个寄存器,写代码的时候可以用R0。


总结为:先使ICatch和DCatch失效,然后关闭ICatch和DCatch,关闭MMU。ICatch关不关无所谓,DCatch必须关闭,因为bootloader要把内核copy到内存,如果使用了DCatch,但是DCatch没配置好,会导致很多数据在DCatch中,影响内核的运行。(本次代码没关闭ICatch)

核心初始化完成,补充:bl跳转指令会将返回地址放到lr寄存器,要记得做完每一步,加上:mov pc,lr。


猜你喜欢

转载自blog.csdn.net/wllinux12138/article/details/80753004