第1课-异常向量表

什么是异常

参考《ARM架构参考手册》A2.6小节。

异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件。

ARM支持7种类型的异常:

  1. 复位
  2. 未定义指令
  3. 软中断
  4. 预取指令出错
  5. 数据终止访问
  6. 中断
  7. 快速中断

每种异常发生时,ARM处理器都会将PC跳转到对应该异常的固定地址去执行异常处理程序,这个固定的地址称为异常向量。通过配置CP15协处理器,可以选择使用正常的异常向量或是高位的异常向量。

由七个异常向量及其处理函数跳转关系组成的表即为异常向量表,用汇编代码表示如下:
Alt text
Alt text

搭建gboot代码框架

完整的gboot工程包含源代码、链接脚本以及Makefile,源代码可以仿照uboot的汇编加C语言两阶段启动方式,先实现第一阶段的汇编程序。
设置异常向量表只需要按顺序设置几个跳转指令即可,可以将跳转语句的地址用.word伪指令存入内存,再使用ldr从内存中装载值。

第2课-设置svc模式

通过修改CPSR寄存器的低5位可以设置处理器的工作模式,使用指令MRS和MSR,代码如下:

mrs    r0,cpsr      ;读取cpsr寄存器的内容到r0
bic    r0,r0,#0x1f  ;使用bic指令将r0低5位进行清零
orr    r0,r0,#0xd3  ;使用orr指令将r0与11010011进行或操作,实际上不止设置成了svc模式,还关闭了irq和fiq
msr    cpsr,r0      ;把修改好的值再设置回cpsr寄存器

第3课-关闭看门狗

看门狗用于在设备死机时自动重启设备。watchdog一般是一个硬件模块,其作用就是在系统死机时,帮助系统实现自动重启。

看门狗可以看作一个硬件计时器,启动计时后,用户必须在计时结束之前重新开始计时,俗称“喂狗”,如果超时的时候还没有重新开始计时,那么它就认为系统死机了,就会自动重启系统,以下是S3C6410的看门狗模块原理图:
Alt text

其中用于控制看门狗功能的寄存器是WTCON,下面是这个寄存器的描述:
Alt text

关闭看门狗功能,只需要禁用看门狗,或是禁用看门狗的复位功能,代码如下:

#define WTCON 0x7E004000    
disable_watchdog:
    ldr r0, =WTCON
    mov r1, #0x0
    str r1, [r0]

第4课-关闭中断

在设置svc模式时将I位和F位设置成1已经关闭了系统的中断,但并没有操作处理器的中断屏蔽寄存器,接下来要做的就是设置中断屏蔽寄存器。

S3C2440

以下是2440的中断处理流程:
Alt text

中断的处理过程如下,带子断的中断源需要先经过子中断保留寄存器SUBSRCPND和子中断屏蔽寄存器SUBMASK,经过过滤后进入中断保留寄存器SRCPND,不带子中断的中断源直接进入SRCPND。位于SRCPND中保存的中断可以分为普通中断IRQ和快速中断FIQ,通过MODE寄存器过滤出FIQ并送往FIQ线,通过中断屏蔽寄存器MASK和MODE寄存器过滤出IRQ再输入Priority进行优先级判断后再送往IRQ线。

接下来要做的事情就是设置屏蔽寄存器MASK将所有中断屏蔽掉,以下是2440的MASK寄存器描述。
Alt text

屏幕中断只需要将INTMSK寄存器的所有位写1即可。

S3C6410

6410使用了向量中断,查看其中断相关寄存器描述,可知VICxINTENCLEAR用于使用或关闭中断,以下这个是寄存器的描述:
Alt text

只需要将这个寄存器的值设置成全1即可,代码如下:

disable_interrupt:
    mvn r1, #0x0
    ldr r0, =0x71200014
    str r1, [r0]
    ldr r0, =0x71300014
    str r1, [r0]

S5PV210

同样去翻看210的中断章节有关寄存器的描述,在section 04_interrupt的1.4小节中可以找到如下描述:
Alt text

可以知道210的中断处理方式与6410类似,都是通过VICINTENCLEAR寄存器来关闭中断,不同之处在于,210支持更多的中断源,所有4个这个的寄存器需要设置。

第5课-关闭mmu和Cache

以下是现代计算机中的分级存储系统
Alt text

Cache是一种容量小但存取速度非常快的存储器,它保存最近用到的存储器中数据的拷贝。对于程序员来说,Cache是透明的。它自动决定保存哪些数据、覆盖哪些数据,按照功能可以将Cache划分为以下两类:
I-Cache:指令Cache,用于缓存指令
D-Cache:数据Cache,用于缓存数据

2440/6410有16KB的I/D Cache,210有32KB的I/D Cache。

MMU用于完成虚拟地址和物理地址的转换,如下图所示:
Alt text

使用虚拟地址可以有效避免进程地址冲突的问题,不同进程对同一虚拟地址的访问将被映射到不同的物理地址上,除此之外,使用虚拟地址还可以让进程使用更大的地址空间,比如32位linux系统下所有进程都有4G的虚拟地址空间可以使用。

MMU和Cache的开关是通过CP15协处理器来控制的,参考芯片核心手册《Arm1176jzfs.pdf》第3.2.7小节,Control寄存器用于控制I/D Cache和MMU,实际使用中,只要关闭DCache和MMU就可以了。在关闭MMU和Cache之前,还需要先让ICache中的数据失效,这可以通过控制CP15的第7个寄存器c7来完成。关闭过程的示例代码如下:

disable_mmu:
    mcr p15, 0, r0, c7, c7, 0  @让I/D Cache都失效
    mrc p15, 0, r0, c1, c0, 0  @读取Control寄存器的值到r0
    bic, r0, r0, #0x7          @将最低三位清零,关闭MMU和DCache
    mcr p15, 0, r0, c1, c0, 0  @将r0的值写入Control寄存器

  • 无标签