基于S3C6410的ARM11学习(四) 核心初始化之设置处理器模式
0赞之前已经设置中断向量表了,下面就要进行设置处理器的模式。
对于ARM11,有8种模式,不同的模式,权限是不一样的。在bootloader开发的时候,我们需要将处理器的模式设置为Supervisor模式,即SVC模式。这样,权限就高了,可以访问ARM的所有资源。用户模式的权限是最低的,而且要从用户模式切换到其他模式的话,只能通过异常的方式。
用户模式(User): ARM处理器正常的程序执行状态
快速中断模式(FIQ): 高速数据传输或通道处理
外部中断模式(IRQ): 通用的中断处理
管理模式(Supervisor): 操作系统使用保护模式
数据访问终止模式(Abort): 当数据或指令预取终止时进入该模式
系统模式(System):运行具有特权的操作系统任务。
这些模式是在CPSR寄存器中设置的。
如下是CPSR寄存器。在最低5位设置处理器的模式。
以下是5位值对应的模式。
图中表的后面有跟着寄存器,这是代表在这个模式下,可以访问的寄存器。
我们知道ARM11是有16个寄存器,R0-R15。但是,在不同的模式下,这16个寄存器有的不一样的。即每个模式有自己的寄存器。
上图,是各个模式下,寄存器的表。
其中R0-R7、R15寄存器和CPSR寄存器,是所有模式都共有的。但是R8-R14就不一样了,有的模式有自己对应的R8-R14寄存器。比如FIQ模式,就有自己的R8-R14,和其他模式的R8-R14不共用。所以这才叫快中断,因为跳转到快中断后,不用备份原来的R8-R14寄存器,因为用的是自己的寄存器。还可以看到,其他模式都是自己的R13寄存器,也就是堆栈寄存器,所以在这些模式下,使用C语言的话,是要重新定义R13的值的。
除了用户模式和系统模式外,其他模式都有SPSR寄存器。这个寄存器就是用来备份跳转模式切换之前那个模式的CPSR的值。这样之前模式的CPSR的值才不会丢失。这样,在切回原模式时,再将SPSR的值给CPSR,就把原模式的CPSR的值也恢复了。因为CPSR的值是很重要的,所以要保证不能丢失。
下面,就是代码的编写了。
设置SVC模式,其实就是写CPSR寄存器的后5位。将值设置为5’b10011.
代码也比较简单了:
set_svc:
# set cpu mode is SVC and disbale irq fiq
# cpsr[4:0] = 0b10011
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
mov pc, lr
先通过mrs指令将CPSR的值读到r0中。
使用bic指令对r0的后5位清零,0x1f = ‘b00011111。
使用orr指令对r0的后8位值设置为’b11010011。后面5位是10011,设置为SVC模式了。前面7位和6位也给设置1了。
从上图,看出7位和6位是普通控制中断和快中断的。
从手册中得到,当置1,表示disable对应的中断,这里就是关闭所有中断。
这样,就完成了处理器的模式SVC设置。
对比STM32,因为没有用汇编写过这些代码,所以没有了解STM32的CPU的模式。如果有对这方面了解的,麻烦告知一下。自己以前写STM32代码的时候,根本就没有考虑过这些。现在学ARM11了,对比才去了解了一些STM32的底层的东西。
另外,有谁知道CPSR在上电时候的初始化的值是多少的话,也麻烦告知下。我试了下,不设置处理器的SVC模式,并且不关中断,程序也是可以执行的,后面的点灯也是可以点亮,我猜测的话,默认为芯片上电的时候,处理器是工作在SVC模式下的,并且中断也都是关闭的。
如果是这样的话,那就意味着设置处理器的模式SVC,我们是可以省略这部分代码的,因为默认为就是这样。
但是,这也只是考虑了上电复位的情况,但是如果是复位有效呢?当我们按下复位键的时候,这里的代码还是需要的,因为这个时候,需要将处理器模式转化为SVC,因为有可能程序执行的时候是在User模式下的,这样的话就会有权限的限制,有些地址处理器就访问不了。并且要关闭中断,因为也有可能中断是开启的,不然会跳转到中断去。以上两种情况,复位的代码就不会正常的执行了。所以就需要这两步操作,保证复位的程序是可以正常按照我们写的顺序执行。
所以,我总结,这里的代码是需要的。为什么呢?因为uboot中也有这代码,要是不需要的话,那么uboot中肯定也不会有。Uboot可是行业的老大啊。
无意中,发现一个介绍uboot的start.S的网站,这个网站对这个启动文件的每一句语句进行了详细的讲解,实在是非常好的资源。对理解uboot有很好的作用。