N、Z、C、V这四位统称为条件标志位。
cpsr的第八位统称为控制位。
返回上面代码分析,mrs指令是读状态寄存器指令,如下所示:
mrs r0, cpsr
这行代码的含义是将cpsr状态寄存器读取,保存到r0中。
bic指令是位清除指令,如下所示:
bic r0, r0, #0x3f
这行代码的作用是将r0的低六位清零。
orr指令是或运算,如下所示:
orr r0, r0, #0xd3
将r0与1101 0011进行或运算,由于之前进行了位清零,那么此时r0的低八位为:1101 0011。
msr指令是写状态寄存器指令,如下所示:
msr cpsr, r0
将r0数据写入cpsr程序状态寄存器。同样cpsr的低八位即为:1101 0011。那么这八位的含义如下。
1) 第七位,即为I位,当I=1时禁止IRQ中断。
2) 第六位,即为F位,当F=1时禁止FIQ中断。
3) 第五位,即为T位,当T=1时执行ARM指令;当T=0时执行Thumb指令。
4) 低五位,即为M[4:0],当M[4:0] = 0x13,即为管理模式。
接着进入cpu_init_crit,即cpu初始化阶段。
3. caches初始化 mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
mov指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。
mov r0, #0
这行代码即表示将0这个立即数加载到r0寄存器中。
mcr指令将ARM处理器的寄存器中的数据传递到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。
mcr p15, 0, r0, c7, c7, 0
指令从ARM寄存器中将数据传送到协处理器p15的寄存器中,其中r0为ARM寄存器,存放源操作数;c7和c7为协处理器寄存器,为目标寄存器;p15和r0之间的0为操作码1;最后0为操作码2。
上面这行代码的作用是向c7写入0将使ICache与DCache无效。
mcr p15, 0, r0, c8, c7, 0
而这行代码的作用是向c8写入0将使TLB失效。
4. MMU初始化 mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
······
mmu_disable:
mcr p15, 0, r0, c1, c0, 0
mrc指令将协处理器寄存器中的数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。
mrc p15, 0, r0, c1, c0, 0
指令将协处理器p15寄存器中的数据传送到ARM寄存器中。其中,r0为ARM寄存器,是目标寄存器;c1和c0为协处理器寄存器,存放源操作数;p15和r0之间的0是操作码1;最后0是操作码2。
V : 表示异常向量表所在的位置,0:异常向量在0x00000000;1:异常向量在 0xFFFF0000。
I : 0 :关闭Icaches;1 :开启Icaches。
R、S : 用来与页表中的描述符一起确定内存的访问权限。
B : 0 :CPU为小字节序;1 : CPU为大字节序。
C : 0:关闭DCaches;1:开启Dcaches。
A : 0:数据访问时不进行地址对齐检查;1:数据访问时进行地址对齐检查。
M : 0:关闭MMU;1:开启MMU。
到这里,再逐句代码分析。
bic r0, r0, #0x00002300
2300即为0010 0011 0000 0000,即是将r0的第13、9、8位清零。
bic r0, r0, #0x00000087
0087即为0000 0000 1000 0111,即是将r0的第7、2、1、0位清零。
orr r0, r0, #0x00000002
5. 外设的基地址初始化#ifdef CONFIG_PERIPORT_REMAP
/* Peri port setup */
ldr r0, =CONFIG_PERIPORT_BASE
orr r0, r0, #CONFIG_PERIPORT_SIZE
mcr p15,0,r0,c15,c2,4
#endif
arm11把内存(memory)区间和外设(peripheral)区间地址分开,在CPU初始化的时候,需要通过协处理器指令CP15告诉CPU外设寄存器的地址范围。如果没有这样做,CPU默认为内存访问,也就无法访问到外设区间的寄存器。