MMU 相关知识
一、什么是MMU
MMU是Memory Management Unit的缩写。
MMU负责虚拟地址与物理地址的转换、权限控制等。
ARM出品的CPU, MMU作为一个协处理器存在 一定是编号为15的协处理器. 可以提供32BIT共4G的地址空间的映射.
二、cache
CPU内核发出VA请求读数据,TLB(translation lookaside buffer)接收到该地址,为什么是TLB先接收到该地址呢?因为TLB是MMU中的一块高速缓存(也是一种cache,是CPU内核和物理内存之间的cache),
它缓存最近查找过的VA对应的页表项,如果TLB里缓存了当前VA的页表项就不必做translation table walk了,否则就去物理内存中读出页表项保存在TLB中,TLB缓存可以减少访问物理内存的次数。
页表项中不仅保存着物理页面的基地址,还保存着权限和是否允许cache的标志。MMU首先检查权限位,如果没有访问权限,就引发一个异常给CPU内核。然后检查是否允许cache,如果允许cache就启动cache和CPU内核互操作。
如果不允许cache,那直接发出PA从物理内存中读取数据到CPU内核。
如果允许cache,则以VA为索引到cache中查找是否缓存了要读取的数据,如果cache中已经缓存了该数据(称为cache hit,cache名字)则直接返回给CPU内核,如果cache中没有缓存该数据(称为cache miss),则发出PA从物理内存中读取数据并缓存到cache中,同时返回给CPU内核。但是cache并不是只去CPU内核所需要的数据,而是把相邻的数据都去上来缓存,这称为一个cache line。ARM920T的cache line是32个字节,例如CPU内核要读取地址0x30000134-0x3000137的4个字节数据,cache会把地址0x30000120-0x3000137(对齐到32字节地址边界)的32字节都取上来缓存。
可以总结出,
(1)一块内存,如果不允许cache,那么访问VA会直接转换为PA,然后进行物理内存的访问。
(2)如果允许cache,且首次访问VA,那么会建立该VA的缓存页表,会从PA读取数据并缓存到cache中,同时返回给CPU;
(3)如果允许cache,且以前访问过VA,那么会先去cache中查找是否缓存了数据,如果cache hit,那么把缓存中的数据返回给CPU,不再去读取PA;如果cache miss,则类似步骤(2),去PA中获取数据。
优点:访问cache比访问物理内存快,所以cache会增加程序运行速度。
缺点:想访问一块内存中的数据,例如网络包数据,但是cache和内存中的数据不一致,我们会访问到cache中的“错误数据”,而不是内存中的实时数据。
三、write through 和 copyback
直写式(write through),即CPU在向Cache写入数据的同时,也把数据写入物理内存以保证Cache和主存中相应单元数据的一致性,其特点是简单可靠,但由于CPU每次更新时都要对主存写入,速度必然受影响。
cache的数据update后,main mem的数据同时update
回写式(write back,copyback),即CPU只向Cache写入,并用标记加以注明,直到Cache中被写过的块要被进入的信息块取代时,才一次写入主存。这种方式考虑到写入的往往是中间结果,每次写入主存速度慢而且不必要。其特点是速度快,避免了不必要的冗余写操作,但结构上较复杂。
cache的数据update后,main mem的数据不同时update(cache line 被称为dirty);直到cache数据无效时,才将main mem的数据 update(cache line被称为clean)。
四、cache一致性问题
CPU和外设异步访问内存时,有cache(数据cache)一致性问题。
例如网络收到数据会存在PA(RAM 0x50000000)处,CPU也会去读该段内存。有可能MAC更新了该段PA的数据,cache里的数据却没更新,那么CPU访问的就是错误数据。
五、VxWorks 解决cache一致性问题
VxWorks下通常有两种方法解决高速缓冲存储器一致性问题
5.1 将某段内存设为non-cacheable
(1)MMU映射时,将该内存段的空间属性为non-cacheable;
(2)在MMU映射为cacheable的内存段后,用cache DmaMalloc()/cache DmaFree()从该内存段中获得buffer。则此段buffer是non-cacheable的。
5.2 flush()/invalidate()
对于cacheable的buffer空间,采用flush()/invalidate()函数或宏来配合读/写使用此段buffer空间.
执行cache flush,cache的数据会被写入物理内存中;
执行cache invalidate,则CPU不读取cache的数据,而去读取物理内存的数据。
实际flush()/invalidate()函数有如下两组,功能相同稍有区别:
组1:CACHE_DMA_FLUSH()函数和CACHE_DMA_INVALIDATE()函数
组2:cacheFlush()函数和cacheInvalidate()函数