C位为1表示允许Cache,这种情况下用B位来表示Write Through还是Write Back。有些页面不允许Cache,置C位为0,这种情况下可以用B位来选择是否允许使用Write Buffer。Write Buffer也是一种简单的Cache,CPU核执行写指令时可以把数据交给Write Buffer,然后由Write Buffer负责写回内存,这时CPU可以执行后续指令而不必等待写回内存这个较慢的操作结束。想一下,既然有Write Buffer,为什么没有Read Buffer?
第四节 启用MMU后地址访问过程
当CPU请求存储器访问时,首先在TLB中查找虚拟地址,如果该虚拟地址对应的地址描述符不在TLB中时,读取内存中页表查询,并将该描述符添加到TLB中,如果TLB已满,根据一定算法进行替换。
在得到该地址描述符后,进行如下操作:
1从描述符表中得到对应的物理地址
2根据域访问控制和描述符中AP位确定是否允许对该内存进行操作。如不,则产生存储访问中止中断
3如访问被允许,根据描述符表中CB位决定是否缓存该内存的访问结果,如不,则根据得到的物理地址直接访问内存,如允许,则首先在CACHE中查找,命中则直接读取,如未命中,则根据物理地址直接访问内存,并将该数据读取到CACHE中。
e
具体编程实现
好了,通过对以上知识的学习,我们已经对ARM地址转换及CACHE的读写有了深刻的认识,因此启动MMU及CACHE,需要如下步骤:
1. 禁止数据CACHE,将C15中寄存器的c1寄存器C[2]清零
mrc p15,0,r0,c1,c0,0
bic r0,r0,#(0x1<<2)
mcr p15,0,r0,c1,c0,0
2. 禁止代码CACHE,将C15中寄存器的c1寄存器I[12]清零
mrc p15,0,r0,c1,c0,0
bic r0,r0,#(0x1<<12)
mcr p15,0,r0,c1,c0,0
3. 禁止MMU,将C15中寄存器的c1寄存器M[0]清零
mrc p15,0,r0,c1,c0,0
bic r0,r0,#0x1
mcr p15,0,r0,c1,c0,0
4. 使数据及代码段CACHE无效
mcr p15,0,r0,c7,c7,0
5. 清空写缓冲区
mcr p15,0,r0,c7,c10,4
6. 使TLB整个页表无效
mcr p15,0,r0,c8,c7,0
7. 设置控制域
mcr p15,0,r0,c3,c0,0 R0->C3;
8. 设置进程PID号
mcr p15,0,r0,c13,c0,0
9. 设置页表基地址
mcr p15,0,r0,c2,c0,0 R0->C2
10. 计算描述符表并添加到TLB指定的内存单元中
由于一级页表由虚地址[31:20]进行索引,共计4096个为16k,由于TQ2440开发板为64M内存,故我们将其放在0x33ffc000处,即64M内存的最未端的16K内存中。
11. 在设置好页表描述符的基础上, 我们启用地址对齐功能,将C1寄存器A[1]赋值为1
mrc p15,0,r0,c1,c0,0
orr r0,r0,#(0x1<<1)
mcr p15,0,r0,c1,c0,0
12. 开启MMU功能,将C1寄存器M[0]赋值为1
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0x1
mcr p15,0,r0,c1,c0,0
13. 开启代码及数据CACHE,将C1寄存器C[2]位,I[12]位赋值为1
mrc p15,0,r0,c1,c0,0
bic r0,r0,#(0x1<<12+0x1<<2)
mcr p15,0,r0,c1,c0,0
经过以上步骤,我们成功开启了MMU及CACHE功能。在本程序中,为了能使用中断功能,我们将0~0x20000000(32M)的地址空间映射到了0x30000000~0x32000000处,这样当中断发生时,CPU到0x18处执行时,实际到物理地址0x30000018处执行,中断就能正常运行了。
虽然我们成功对0x0开始的地址进行了映射,但还有一个关键问题未解决,当CPU执行mcr p15,0,r0,c1,c0,0这条指令后,MMU功能开启,而这条指令的下一条指令已经开始译码并执行,而这条指令的地址已经通过MMU进行转换,那么此时程序如何保证能得到正确的物理地址而正确执行呢?如果我们将0x30000000映射到0x30000000,即虚拟地址与物理地址一致,显然程序能够正确执行。这也是ARM推荐使用这种方法。
TQ2440-TEST程序映射关系:
通过以上分析,我们确保了程序的正确运行,但又产生了新的问题,也就是说我们的程序必须保证在0x0和0x30000000均能正确运行,对于这个问题,我在前几章已经做过分析。一句话,确保程序是基于PC+8+偏移量的寻址方式。
我们完全可以将0x0处的地址映射到0x30000000处,其它地址映射保持不变,即虚拟地址与物理地址一致。这样地址映射对我们来说完全是透明的,在开发程序时,我们完全可以不用考虑它,最后调用它就行。
文章评论(0条评论)
登录后参与讨论