ARM Bootloader:禁用MMU和缓存 [英] ARM Bootloader: Disable MMU and Caches

查看:418
本文介绍了ARM Bootloader:禁用MMU和缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据一些教程,我们将在引导程序开始时禁用MMU和I/D缓存.如果我理解正确,它的目的是直接在程序中使用物理地址,因此,如果我输入错误,请更正我.谢谢!

According to some tutorials, we will disable MMU and I/D-Caches at the beginning of bootlaoder. If I understand correctly, it aims to use the physical address directly in the program, so please correct me if I'm wrong. Thank you!

第二,我们这样做是为了禁用MMU和缓存:

Secondly, we do this to disable MMU and Caches:

mrc P15、0,R0,C1,C0、0

mrc P15, 0, R0, C1, C0, 0

bic R0,R0,#0x00002300 @清除第13、9:8位

bic R0, R0, #0x00002300 @ clear bits 13, 9:8

bic R0,R0,#0x00000087 @清除第7位,2:0

bic R0, R0, #0x00000087 @ clear bits 7, 2:0

orr R0,R0,#0x00000002 @设置位2(A)对齐

orr R0, R0, #0x00000002 @ set bit 2 (A) Align

orr R0,R0,#0x00001000 @设置位12(I)I-Cache

orr R0, R0, #0x00001000 @ set bit 12 (I) I-Cache

mcr P15、0,R0,C1,C0、0

mcr P15, 0, R0, C1, C0, 0

D缓存,MMU和数据地址对齐故障检查已通过清除位2:0禁用,但是为什么我们在以下仪器中立即启用位2?要确保此操作有效?

D-Cache, MMU and Data Address Alignment Fault Checking have been disabled by clear bits 2:0, but why we enable bit 2 immediately in the following instrument? To make sure this manipulation is valid?

最后一个问题是为什么禁用D-cache但I-cache是​​能够的?要加快仪器处理速度?

Last question is why D-cache is disabled but I-caches is able? To speed up instrument process?

推荐答案

最后一个问题是为什么禁用D-cache但I-cache是​​能够的?要加快仪器处理速度?

Last question is why D-cache is disabled but I-caches is able? To speed up instrument process?

MMU具有用于确定哪些内存区域可缓存的设置.如果您没有打开mmu,但是打开了数据缓存(如果可能),则无法安全地与外围设备通信.例如,如果您像读取任何其他数据操作一样读取通过缓存的uart状态寄存器,则无论该状态如何,它都会保留在缓存中以供后续读取,直到该缓存行被逐出并且您在实际操作中又得到了一击登记.例如,假设您有一些代码轮询uart状态寄存器,以等待rx缓冲区中的字符.如果第一次读取显示没有字符,则该状态进入高速缓存,您将永远处于循环中,因为您将再也无法与状态寄存器通信,您将仅获取该寄存器的高速缓存副本.如果那里有一个字符,那么该状态也会被缓存,您读取rx寄存器,然后执行某些操作,如果再次返回该状态(如果尚未从数据缓存中清除该状态),则会得到过时的状态,该状态显示有一个字符,您对rx缓冲区的读取可能也可能不被缓存,因此您可能会在缓存中获取过时的值,您可能会得到过时的值,或者在读取时外围设备执行的操作而没有新值,或者您可能获得新的价值,但是在这些情况下您没有得到的是正确访问外围设备.启用mmu时,您可以使用mmu将该外设使用的地址空间标记为不可缓存(数据),并且不会出现此问题.禁用mmu后,您需要为Arm系统关闭数据缓存.

The MMU has settings to determine which memory regions are cacheable or not. If you do not have the mmu on but you have the data cache on (if possible) then you cannot safely talk to peripherals. if you read the uart status register for example that goes through the cache just like any other data operation, whatever that status is stays in the cache for subsequent reads until such time as that cache line is evicted and you get one more shot at the actual register. Lets say for example you have some code that polls the uart status register waiting for a character in the rx buffer. If that first read shows there is no character, that status goes in the cache, you will remain in the loop forever since you will never get to talk to the status register again you will simply get the cached copy of the register. if there was a character in there then that status also gets cached, you read the rx register, and perhaps do something, if when you come back again if the status has not been evicted from the data cache then you get the stale status which shows there is a character, you rx buffer read may or may not also be cached so you may get the stale value in the cache, you may get a stale value or whatever the peripheral does when you read and there is no new value or you might get a new value, but what you dont get in these situations is proper access to the peripheral. When the mmu is on, you use the mmu to mark the address space used by that peripheral as non-(data)-cacheable, and you dont have this problem. With the mmu off you need the data cache off for arm systems.

保持I高速缓存正常运行是因为指令只能读取读取的指令...对于一个裸机应用程序来说还可以,例如,如果您使用的闪存可能会造成读取干扰(spi或i2c闪烁).问题在于此应用程序是引导加载程序,因此您必须格外小心.例如,您的引导加载程序在地址0x8000处有一些代码,它至少运行了一次,然后您选择将其用作引导加载程序,该引导加载程序可能位于地址0x10000000,允许您在0x8000处加载新程序,此加载过程使用数据访问,因此它不会通过指令高速缓存.因此,指令高速缓存有可能包含上次您在0x8000区域中时的部分或全部代码,并且当您跳转到0x8000的引导加载的代码时,您可能会从高速缓存中获取旧程序或讨厌的混合物旧程序和新程序的一部分,用于缓存和不缓存的部分.因此,如果您的引导加载程序允许打开i高速缓存,则需要在分支到引导加载的代码之前使高速缓存无效.

Leaving the I-cache on is okay because instruction fetches only read instructions...Well for a bare metal application that is okay, it helps for example if you are using a flash that has a potential for read disturb (spi or i2c flashes). The problem is this application is a bootloader, so you must take some extra care. For example your bootloader has some code at address 0x8000 that it runs through at least once, then you choose to use it as a bootloader, the bootloader might be at say address 0x10000000 allowing you to load a new program at 0x8000, this load uses data accesses so it does not go through the instruction cache. So there is a potential that the instruction cache has some or all of the code from the last time you were in the 0x8000 area, and when you branch to the bootloaded code at 0x8000 you will get either the old program from cache or a nasty mixture of old program and new program for the parts that are cached and not cached. So if your bootloader allows for the i-cache to be on, you need to invalidate the cache before branching to bootloaded code.

最后,如果您或使用此引导加载程序的任何人都想使用jtag,那么您将遇到相同的问题,但更糟的是,如果不告诉i缓存,则不经过i高速缓存的数据周期将被用于写入新程序使用jtag调试器运行新程序,您将获得1)仅新程序,2)新程序和来自缓存的旧程序片段的混合3)来自缓存的旧程序.

Lastly, if you or anyone using this bootloader wants to use jtag, then you have that same problem but worse, data cycles that do not go through the i-cache are used to write the new program to ram, when you tell the jtag debugger to then run the new program you will get 1) only the new program, 2) a mixture of the new program and old program fragments from cache 3) the old program from cache.

因此,没有mmu的d-cache不好,因为ram,外围设备等中没有的东西.i-cache是​​一种风险自负的用途,除了jtag的使用时间外,您可以减轻它的风险.用于调试.

So d-cache is bad without an mmu because of things that are not in ram, peripherals, etc. The i-cache is a use at your own risk kind of thing which you can mitigate except for the times that jtag is used for debugging.

如果您有疑问或在(外部)闪存中确认了读取干扰,那么我建议您打开i缓存,使用紧密循环将您的应用程序复制到ram,分支到ram副本并在其中运行,关闭i缓存(或使用后果自负),并且不要再次触摸闪光灯,这当然不是对小区域的大量读取访问.像您可能在命令行解析器中遇到的那样,一个紧密的uart轮询循环是一个很好的阅读干扰源.

If you have concerns or have confirmed read-disturb in your (external) flash, then I recommend turn on the i-cache, use a tight loop to copy your application to ram, branch to the ram copy and run there, turn off the i-cache (or use at your own risk) and dont touch the flash again, certainly not heavy read accesses to small areas. A tight uart polling loop like you might have for a command line parser, is a really good place to get hit with read-disturb.

这篇关于ARM Bootloader:禁用MMU和缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆