ARM 引导加载程序:禁用 MMU 和缓存 [英] ARM Bootloader: Disable MMU and Caches

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

问题描述

根据一些教程,我们会在bootlaoder开始时禁用MMU和I/D-Caches.如果我理解正确,它的目的是在程序中直接使用物理地址,所以如果我错了,请纠正我.谢谢!

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 @ set bit 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-Cache、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-caches 可以?加快仪器进程?

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

推荐答案

最后一个问题是为什么 D-cache 被禁用而 I-caches 可以?加快仪器进程?

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-cache 是可以的,因为指令只获取读取指令......对于裸机应用程序来说是可以的,例如,如果您使用具有读取干扰潜力的闪存(spi 或i2c 闪烁).问题是这个应用程序是一个引导加载程序,所以你必须格外小心.例如,您的引导加载程序在地址 0x8000 处有一些代码,它至少运行一次,然后您选择将其用作引导加载程序,引导加载程序可能位于地址 0x10000000 允许您在 0x8000 加载新程序,此加载使用数据访问,因此它不会通过指令缓存.因此,指令缓存有可能包含您上次进入 0x8000 区域时的部分或全部代码,当您分支到 0x8000 处的引导加载代码时,您将从缓存中获取旧程序或令人讨厌的混合缓存和未缓存部分的旧程序和新程序.因此,如果您的引导加载程序允许启用 i-cache,则您需要在跳转到引导加载代码之前使缓存无效.

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,那么您会遇到同样的问题,但更糟糕的是,当您告诉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 很糟糕,因为内存、外围设备等中没有的东西. 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-cache,使用紧密循环将您的应用程序复制到 ram,分支到 ram 副本并在那里运行,关闭 i-cache(或使用风险自负)并且不要再次接触闪存,当然不要对小区域进行大量读取访问.像命令行解析器那样的紧密 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 引导加载程序:禁用 MMU 和缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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