MPU ( Memory Protection Unit
) ist eine Funktion von ARM-Prozessoren, die Speicherschutz- und Zugriffskontrollfunktionen bietet und normalerweise zur Implementierung der Speicherisolation und des Schutzes von Betriebssystemen verwendet wird. Beispielsweise können wir den gesamten RAM auf nicht ausführbar setzen, sodass Code-Injection-Angriffe vermieden werden können. Bei der Durchführung kürzlich durchgeführter Projekte verwendeten mehrere Cortex-Kerne MPU. Ich habe festgestellt, dass MPU nicht nur eine Rolle beim Speicherschutz spielt, sondern auch mit dem Cache zusammenhängt und auch die Zugriffsgeschwindigkeit externer Speichergeräte beschleunigen kann. In diesem Artikel wird die MPU im Detail vorgestellt.
Artikelverzeichnis
Hier nehmen wir den Kern der Cortex-M7-Serie als Beispiel, um die MPU vorzustellen. Tatsächlich sind Cortex-M-Kerne in Bezug auf MPUs grundsätzlich gleich, mit Ausnahme von Cortex-M33, der die Unterregion und überlappende Funktionen aufhebt, weil Es kann jede Bereichsgröße flexibler anpassen.
1 MPU-Funktionen
Die MPU ermöglicht einem Prozess den Zugriff auf 16 Speicher- oder Peripheriebereiche (0–15), und die Position und Größe jedes Bereichs (muss 2^n und größer als 32 Byte sein) ist konfigurierbar.
- Jeder Bereich kann weiter in bis zu 8 Unterbereiche unterteilt werden, und die Größe jedes Unterbereichs beträgt mindestens 32 Byte, was durch die Länge der Cache-Zeile bestimmt wird
- Zusätzlich zu den 16 Regionen gibt es eine Standardregion mit der Nummer -1, die die niedrigste Priorität hat
- Diese Regionen können sich überlappen oder verschachtelt sein . Region 15 hat die höchste Priorität und Region 0 die niedrigste Priorität, was das Verhalten der Regionsüberlappung bestimmt.
Schauen wir uns ein Beispiel an:
Die obige Abbildung zeigt ein Beispiel mit sechs Regionen. Region 4 überschneidet sich mit den Regionen 0 und 1 und Region 5 ist in Region 3 enthalten. Da die Prioritäten aufsteigend sind, haben überlappende Bereiche (orange) Vorrang. Wenn also Bereich 0 beschreibbar ist und Bereich 4 nicht, sind Adressen, die sich zwischen 0 und 4 überschneiden, nicht beschreibbar.
- Die MPU unterscheidet nicht zwischen Zugriffsrechten für Anweisungen und Daten, sondern nutzt denselben Bereich, um den Zugriff auf Daten und Anweisungen zu steuern.
- Die MPU kann auch andere Speicherattribute definieren, beispielsweise die Cachefähigkeit einer Region, die an die Cache-Einheit oder den Speichercontroller des Systems übergeben werden.
- Die ARM-Architektur unterstützt zwei Cache-Ebenen: internen Cache (
L1-Cache
) und externen Cache (L2-Cache
). Unter diesen befindet sich der L1-Cache in der Nähe des Prozessorkerns, der dem Prozessor am nächsten ist, und bietet die schnellste Zugriffsgeschwindigkeit. Der L2-Cache befindet sich außerhalb des L1-Cache, weiter vom Prozessor entfernt, ist aber immer noch schneller als der Hauptspeicher und bietet eine größere Kapazität.
- Die ARM-Architektur unterstützt zwei Cache-Ebenen: internen Cache (
2 Speichertypen
Im Allgemeinen gibt es drei gängige Speichertypen:
1. Normal Memory
: Ermöglicht der CPU die effiziente Durchführung von Lade- und Speichervorgängen für Bytes, Halbwörter und Wörter (der Compiler kennt den Speicherbereichstyp nicht). Bei gewöhnlichen Speicherbereichen wird die Reihenfolge der Lade- und Speichervorgänge nicht unbedingt in der im Programm aufgeführten Reihenfolge ausgeführt.
2. Device Memory
: Lade- und Speichervorgänge werden streng durchgeführt, um sicherzustellen, dass die Register in der richtigen Reihenfolge eingestellt werden.
3. Strongly Ordered Memory
: Alle Vorgänge werden in strikter Übereinstimmung mit der im Programm aufgeführten Reihenfolge ausgeführt, und die CPU wartet auf den Abschluss der Lade-/Speicheranweisung, bevor sie die nächste Anweisung im Programmablauf ausführt. Dies kann zu Leistungseinbußen führen.
3 Speicherattribute
Das Bereichsattribut- und Größenregister MPU_RASR
( Region Attribute and Size Register
) der MPU wird zum Festlegen aller Speicherattribute verwendet. Die Funktionen jedes Felds des Registers sind in der folgenden Tabelle aufgeführt:
Bits | Name | Beschreibung |
---|---|---|
28 | XN | Niemals ausführen |
26:24 | AP | Feld für die Datenzugriffsberechtigung (RO, RW oder Kein Zugriff) |
21:19 | TEX | Typerweiterungsfeld |
18 | S | Teilbar |
17 | C | Cachebar |
16 | B | Pufferbar |
15:8 | SRD | Unterregion deaktiviert. 1 = deaktiviert, 0 = aktiviert |
5:1 | GRÖSSE | die Größe des MPU-Schutzbereichs |
(1) XN
: Steuern Sie die Ausführung des Codes. Zu diesem ZeitpunktXN=1
wird auf den entsprechenden Speicherbereich zugegriffen MemManage Fault
.
(2) AP
: Steuern Sie die Zugriffsrechte des Speicherbereichs, wie in der folgenden Tabelle gezeigt
AP[2:0] | Privilegierte Berechtigungen | Unprivilegierte Berechtigungen | Beschreibung |
---|---|---|---|
000 | Kein Zugang | Kein Zugang | Alle Zugriffe erzeugen einen Berechtigungsfehler |
001 | RW | Kein Zugang | Zugriff nur über eine privilegierte Software |
010 | RW | RO | Das Schreiben durch eine unprivilegierte Software führt zu einem Berechtigungsfehler |
011 | RW | RW | Voller Zugriff |
100 | Unvorhersehbar | Unvorhersehbar | Reserviert |
101 | RO | Kein Zugang | Nur von einer privilegierten Software gelesen |
110 | RO | RO | Nur lesen, von privilegierter oder nicht privilegierter Software |
111 | RO | RO | Nur lesen, von privilegierter oder nicht privilegierter Software |
(3) S
: Gibt an, ob der Speicherbereich gemeinsam genutzt werden kann. Wenn eine Region gemeinsam genutzt werden kann, können mehrere Busmaster gleichzeitig darauf zugreifen und das System stellt Mechanismen zur Datensynchronisierung bereit. Wenn eine Region jedoch nicht gemeinsam genutzt werden kann, ist Software erforderlich, um die Kohärenz der Daten zu steuern, auf die mehrere Busse zugreifen.
- Bei einigen Chips wird der Datensynchronisationsmechanismus der Hardwareschicht nicht unterstützt,
S
daher wird er verwendet, um anzugeben, ob der Bereich vorhanden istnon-cacheable
(4) TEX
, C
, B
: Diese drei Felder definieren die Cache-Eigenschaften des Speicherbereichs und können bis zu einem gewissen Grad dessen Gemeinsamkeit bestimmen ( S
Feld)
TEX | C | B | Speichertyp | Beschreibung | Teilbar |
---|---|---|---|---|---|
000 | 0 | 0 | Dringend bestellt | Dringend bestellt | Ja |
000 | 0 | 1 | Gerät | Geteiltes Gerät | Ja |
000 | 1 | 0 | Normal | Durchschreiben, keine Schreibzuweisung | S bisschen |
000 | 1 | 1 | Normal | Zurückschreiben, keine Schreibzuweisung | S bisschen |
001 | 0 | 0 | Normal | Nicht zwischenspeicherbar | S bisschen |
001 | 0 | 1 | Reserviert | Reserviert | Reserviert |
001 | 1 | 0 | Nicht definiert | Nicht definiert | Nicht definiert |
001 | 1 | 1 | Normal | Zurückschreiben, Schreiben und Lesen zuordnen | S bisschen |
010 | 0 | 0 | Gerät | Nicht gemeinsam nutzbares Gerät | NEIN |
010 | 0 | 1 | Reserviert | Reserviert | Reserviert |
- Wenn
shareable
das Bit 1 ist, wird die Cache-Strategie nichtTEX/C/B
durch das Feld beeinflusst, sondern als festgelegtnon-cacheable
Bufferable
undCacheable
der Unterschied?Bufferable
Es konzentriert sich hauptsächlich auf die Lese- und Schreibeffizienz des Speicherzugriffs, der verwendet wird, um Daten vorab abzurufen oder zu entscheiden, wann Daten gemäß ihrer Pufferstrategie in den Speicher zurückgeschrieben werden sollen. Attribute hingegenCacheable
konzentrieren sich auf die Geschwindigkeit des Datenzugriffs und ermöglichen es dem Prozessor, Daten für einen schnelleren Zugriff im Cache zu speichern.Write through with no write allocate
: Bei einem Treffer (erforderliche Daten sind im Cache vorhanden) werden Daten in den Cache und den Hauptspeicher geschrieben. Bei einem Fehlschlag wird nur der Block im Hauptspeicher aktualisiert, ohne in den Cache zu schreiben.Write-back with no write allocate
: Wenn der Prozessor einen Schreibvorgang ausführt und sich die Daten bereits im Cache befinden, werden nur die Daten im Cache aktualisiert und nicht sofort in den Hauptspeicher zurückgeschrieben. Erst wenn die Daten im Cache ersetzt werden müssen, werden die neuesten Daten in den Hauptspeicher zurückgeschrieben.Write-back with write and read allocate
: Wenn der Prozessor einen Schreibvorgang ausführt und sich die Daten bereits im Cache befinden, aktualisieren Sie die Daten im Cache und schreiben Sie sie in den Hauptspeicher. Wenn der Prozessor einen Lesevorgang ausführt, sind die Daten nicht im Cache vorhanden, sondern er liest den gesamten Block aus dem Hauptspeicher in den Cache
(5) SRD
: Markieren Sie den aktivierten oder deaktivierten Status eines bestimmten Unterbereichs. Wenn ein Unterbereich deaktiviert ist, wird der Zugriff innerhalb dieses Unterbereichs durch andere aktivierte Bereiche überlagert. Wenn keine anderen aktivierten Regionen die deaktivierte Unterregion überlappen, generiert die MPU einen Fehler, der angibt, dass der Zugriff illegal oder nicht erlaubt ist.
Hinweise zu Cortex-M7 :
(1) TCM
( Tightly Coupled Memories
, Eng gekoppelter Speicher) wird immer als nicht zwischenspeicherbarer, nicht gemeinsam genutzter gewöhnlicher Speicher behandelt, unabhängig davon, welche Speichertypattribute die MPU für den Speicherbereich im TCM definiert.
(2) speculative prefetch
Prefetching ist eine Optimierungstechnik des Prozessors, mit der Daten vorab aus dem Hauptspeicher in den Cache des Prozessors geladen werden, damit bei Bedarf schneller darauf zugegriffen werden kann. Da der Prozessor jedoch nicht im Voraus genau wissen kann, welche Daten tatsächlich verwendet werden, können Vorabrufvorgänge manchmal zu unnötigem Overhead führen. Dies betrifft einige Speicher oder Geräte, die auf Mehrfachzugriffe empfindlich reagieren, wie z. B. FIFOs, LCD-Controller usw. Gleichzeitig kann es die Bandbreite anderer Master-Geräte wie LCD oder DMA belegen.
Um den Leistungsverlust durch unnötiges Prefetching zu vermeiden, führt der Cortex-M7-Prozessor constraint speculative prefetch
Einschränkungen ein. Dies bedeutet, dass der Prozessor in einigen Fällen den Vorabrufvorgang einschränkt und den Vorabrufvorgang nicht durchführt, z. B. indem er den Speichertyp in Device Memory
oder über das Speicherattribut der MPU ändert Strongly Ordered Memory
.
4 MPU-Konfigurationsbeispiel für I.MX RT1170
Für den Cortex-M7-Kern von I.MX RT1170 können wir die folgenden Makros verwenden, um einen MPU-Bereich zu definieren ARM_MPU_RBAR
und zu konfigurieren:ARM_MPU_RASR
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
MPU->RBAR = ARM_MPU_RBAR(Region, BaseAddress);
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
MPU->RASR = ARM_MPU_RASR((DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size));
Die Standard-MPU-Konfiguration im RT1170 ist sehr lang und ich habe einen Teil weggelassen, da einige Speicherkonfigurationen gleich sind. Darüber hinaus habe ich auch die Initialisierung von Cache-bezogenen Segmenten weggelassen. Ich werde in Zukunft einen Artikel über ICache und DCache zur Analyse schreiben. Das Folgende ist der Standard-MPU-Konfigurationscode in RT1170:
- Die Basisadresse der Region muss auf ein ganzzahliges Vielfaches der Regionsgröße ausgerichtet sein
/* Region 0 setting: Instruction access disabled, No data access permission. */
MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB);
/* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
/* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
/* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
/* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back. */
MPU->RBAR = ARM_MPU_RBAR(8, 0x30000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_16MB);
(1) Region 0 : Ordnen Sie die gesamte Adresse des Chips zu, dh der maximale Adressbereich der 32-Bit-Adressierung beträgt 4G, und die Standardzuweisung ist nicht ausführbar und nicht zugänglich. Dies liegt daran, dass die Konfiguration der MPU durch eine Konfiguration mit hoher Priorität überschrieben werden kann. Dies bedeutet also, dem Speicherbereich, der später nicht konfiguriert wird, eine Standardberechtigung zuzuweisen. (2) Region 1: Dies ist die Zuordnungsadresse von SDRAM,
hier wird es definiert als Device Memory
, dh non-shareable
. Zeigt an, dass die CPU-Prefetch-Funktion für diesen Speicher abgebrochen wurde.
(3) Region 3 : Stellen Sie den Speicher auf 0x00000000~0x40000000 ein Device Memory
und Region 0
legen Sie den gleichen Standardwert fest.
(4) Region 4 : Dies ist die Adresse des ITCM des Systems. Stellen Sie den Speichertyp auf ein Normal Memory
. Hier ist es auf non-shareable
, cacheable
und gesetzt bufferable
, was angibt, dass die Daten im Cache verwendet werden und nur in den Speicher geschrieben werden, wenn die Cache-Daten ausgelagert werden
(5) Region 8 : Dies ist die Zuordnungsadresse von NOR Flash und Region 4
die Die Konfiguration von und ist grundsätzlich dieselbe, mit Ausnahme von NOR. Wenn Sie bei Flash die FlexSPI-Zuordnung verwenden, ist dieser Speicher schreibgeschützt. Wenn Sie NOR-Flash schreiben müssen, müssen Sie die Funktion von FlexSPI aufrufen xfer
, um den entsprechenden Schreibzeitpunkt zu generieren
- Es gibt auch Speicher für die
AIPS
Konfigurationsregisterzuordnung, der hier ebenfalls weggelassen wird und tatsächlich konfiguriert istDevice Momory
.