×
单片机 > 单片机程序设计 > 详情

基于S3C6410的ARM11学习(七) 核心初始化之关闭MMU和CACHE

发布时间:2020-09-01 发布时间:
|

在关闭了所有中断后,就要关闭MMU和CACHE了。因为这个时候,还在初始化环境,这两个东西是用不到的。所以就需要把他们都关闭,免得影响我们的初始化。

    

MMU是Memory Management Unit的缩写,中文名是存储器管理单元。主要是两个功能:


1、虚拟地址转换为物理地址


2、实现内存的保护


至于具体的MMU的一些知识,等后面用到了在说明了。目前,只需要将MMU给关掉即可。


这个时候,我们需要查看S3C6410的核ARM1176JZFS手册。在这里,我们要接触到一个系统控制处理器,CP15。也叫做协处理器。



手册中说明了,CP15系统控制处理器的作用,主要是6个:


1、整个系统的控制和配置


2、CACHE的配置和管理


3、TCM控制和管理


4、MMU控制和管理


5、DMA控制


6、系统运行监控


CP15共有16组寄存器。每一组寄存器有不同的功能。每一组寄存器下又有若干个寄存器。


至于这些寄存器的功能,在手册中有说明。不过手册是以功能划分寄存器的。如对应MMU功能。


图中,就列出了MMU功能对应的寄存器组。总共用到了c0,c2,c3,c5,c6,c8,c10,c13,c15这9组寄存器。但是也不是每一组寄存器组的所有寄存器都需要到,所有后面通过Opcode_1,CRm,Opcode_2来标识是对哪一个寄存器。


下面是对协处理器访问的用法



MCR指令是对协处理对应的寄存器下的某个寄存器写数据,写的数据放在Rd寄存器中。


MRC指令是对协处理对应的寄存器下的某个寄存器读数据,读的数据放在Rd寄存器中。


说明各个参数意义:


Opcode_1: 操作符1,协处理器行为操作码,对于 CP15 来说, 


 CRn:协处理器的寄存器组编号,编号从c0-c10。


 Rd: 寄存器编号,r0-r14.


 Opcode_2: 访问寄存器组下的寄存器提供附加信息


       CRm: 寄存器组下的寄存器编号。


上面参数,在对应功能的图中都有说明。例如:


我们要写TLB type Register,写的值存在r0寄存器中。



那么从图中,对应


参数

Opcode_1

0

CRn

c0

Rd

r0

Opcode_2

3

CRm

c0


在使用MCR指令。


mcr p15,0,r0,c0,c0,3  


这样,就将r0的值写入到TLB type Register中去了。


CACHE是高速缓冲存储器。CPU工作速度是很快的,而外部内存是工作很慢的,所以当CPU对内存访问的时候,是要等待内存访问结束的。所以中间CPU就在等待,这就浪费了时间。所以在CPU和内存之间加一个CACHE,当CPU写数据到内存中的时候,就先写入到CACHE中,然后CACHE再写入到内存中。CPU写CACHE是很快的,所以就提高了写数据的效率。读数据的话,CPU先在CACHE中去找数据,没有找到的话,CACHE将数据从内存中取出来,再给CPU,同时把这个数据存起来。当CPU在CACHE中找到数据的话,就直接使用这个数据,就不用再去内存中取数据了。


上面两个图就说明了有CACHE和没有CACHE的区别。


在初始化阶段,我们是不是用这CACHE的。


CACHE在ARM11中是分类两种的。一种是存储指令的,一种是存储数据的。



这个在S3C6410的数据手册中有说明。看出来,I/DCACHE大小是16KB。所以以下的操作要分开对ICACHE和DCACHE操作。


我们要对MMU,CACHE控制,所以这里就对CP15的MMU,CACHE功能进行配置。我们知道在ARM中,对任何功能配置都是通过寄存器配置的,所以就需要去配置CP15的MMU,CACHE功能开启和关闭的寄存器。


注意,这个时候,这个寄存器就不能去MMU,CACHE功能部分去找了。而要去找系统控制和配置里面去找了


这个寄存器就是c1寄存器组下的控制寄存器。



直接看这个寄存器的各个位的功能。


这里就截取图中一部分,因为这部分中和MMU,CACHE有关。



最后1位,就是MMU的开启和关闭了。当为0的时候,MMU是关闭的,为1的话,MMU就是打开的。所以这里我们要写入0.将MMU关掉。


该寄存器的第2位,是控制DCACHE的。0关掉。所以这里我们要写入0.将DCACHE关掉。


该寄存器的第12位,是控制ICACHE的。0关掉。所以这里我们要写入0,将ICACHE关掉。


在关闭CACHE之前,还要做一件事,就是要将CACHE的原有的数据给清掉。因为有可能之前,里面就有一些数据了。这个操作也是由CP15下的一个寄存器控制的。



首先找到CACHE相关的寄存器组。看出是c7.



在去看CP15的各个寄存器组的功能。


得知c7组下的c7寄存器是对CACHE数据无效操作的。



再在c7组下的c7寄存器中去找,有上面这张表。


表中都给了汇编指令,怎么对两个CACHE都无效掉。所以,在程序中就直接使用该汇编指令即可。这里Rd可以是任意,因为这里什么值对该命令是没有影响的。


下面就可以开始编写代码了



1、先对两个CACHE中的数据无效掉。使用手册中的汇编,这里Rd使用r0。


2、将CP15的控制寄存器的数据先读出来存在r0中。


3、对r0寄存器数据中第0位,第2为清零。


4、在将r0数据写入到控制寄存器中,这样,就实现了控制寄存器的MMU关闭和DCACHE关闭


5、程序返回。


这里,只是对DCACHE对应的位清零了,使DCACHE关闭,而没有使ICACHE对应的位清零,关闭ICACHE。对于这里,国嵌解释说,在初始化的时候,对ICACHE的要求没有DCACHE那么严格,可以不用关闭,也可以关闭,而DCACHE就必须关闭。至于为什么,目前也不清楚,因为现在也才是初学,等以后学习深了应该就知道了。现在学习,就先跟着前辈们的路走。


对比STM32,这两步就简单了,因为根本就不用做。为什么了,因为STM32中就没有两个东西。都没有了,你怎么操作他。


STM32没有MMU,所以,你在STM32上面就跑不出LINUX系统,因为不能将虚拟内存转换为物理内存。STM32对地址操作都是操作的物理地址。这样,就有很大的局限性。


就这样,我们就完成了核心初始化之关闭MMU和CACHE了。

 

文中若有什么错误,麻烦各位指出,我会虚心的更改的。以免误人学习。也欢迎各位与我交流。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32单片机的复用端口初始化的步骤及方法