Before we start, let us build every word and register field this page uses — nothing is assumed. Read the vocabulary block, then study the two picture-maps below it; the traps refer back to them.
The next picture shows how a guard region overlaps a stack and why alignment and priority matter:
Look at the amber guard band at the bottom of the stack (low addresses). The broad cyan stack region and the amber guard overlap there — and because the guard has the higher region number, its "no access" rule wins on those bytes.
This second picture shows a region cut into its 8 subregions and one slice disabled:
The region is one power-of-two block; the dashed white lines split it into 8 equal eighths, and the amber-crossed slice is the one whose subregion-disable bit is set — a hole punched without moving the base.
An MPU translates virtual addresses to physical addresses like an MMU does.
False. An MPU works purely on physical addresses — it only permits or denies accesses, it never remaps them; translation is an MMU job.
If no MPU region matches an address, the access is always denied.
False. It depends on PRIVDEFENA: if set, privileged code gets a default background map for unmatched addresses; if clear, the unmatched access faults.
A stack guard region must be large to catch overflows.
False. It only needs to be the minimum 32 bytes — the overflow crosses the boundary and the first byte inside the guard faults regardless of guard width.
Marking the stack Execute-Never (XN) stops all stack overflows.
False. XN stops executing injected code on the stack; it does nothing to stop the write that overflows. You need a guard region for that. See Buffer overflow attacks.
When two regions overlap on ARM Cortex-M, the lower-numbered region wins.
False. The highest-numbered matching region wins, which is exactly why the restrictive guard must be given the higher number.
An MPU makes a real-time system slower and less predictable.
False. The permission check happens in the same cycle as the access with fixed latency, so it preservesdeterminism — faults occur at a bounded, known time.
A 1 KB region can start at address 0x2000_0010.
False. Base must align to region size; a 210 region needs its low 10 bits zero, so the nearest legal base is 0x2000_0000.
The MPU can protect a peripheral so user tasks fault but the kernel still writes to it.
True. Set the AP field to privileged-RW / user-none; the peripheral is reachable in privileged mode and faults in user mode.
Enabling the MPU without configuring any regions is safe.
False (usually). With PRIVDEFENA off, every address — including code you're running — has no matching region and faults instantly, hanging the boot.
Subregion disable lets you protect an arbitrary byte range inside a region.
Partly — it only lets you switch off whole eighths of the region, and only for regions ≥256 B; you cannot carve a hole finer than one-eighth of the region size.
"I set base = 0x20000010 for a 64-byte region to protect bytes 0x10–0x50."
The hardware masks the low 6 bits of a 26 region's base, so it silently protects 0x2000_0000–0x2000_0040 — not the window you wanted. Realign your layout instead.
"Guard is Region 0 (I configured it first), broad RW stack is Region 1."
Backwards priority. The higher number (Region 1, the RW stack) wins on overlap, so the guard is ignored and overflows go undetected. Give the guard the higher number.
"I placed the guard region at the top of a downward-growing stack."
A downward stack overflows off its low end, so the guard must sit at the bottom boundary; a top guard never gets hit. Check growth direction in Stack memory layout.
"MemManage fault fired, so I read the faulting address from a global variable I made."
You should read the hardware MMFAR register (MemManage Fault Address Register) and first check its valid-bit in MMFSR (the fault status register) — that hardware pair records the offending address for the handler.
"To carve a hole in a big region I lowered its size."
Shrinking size moves the whole boundary; to punch a hole use subregion disable (each region splits into 8 eighths and you switch off individual slices), which removes one-eighth pieces without touching the base.
"I gave the heap AP = RW and left XN clear because heaps only hold data."
Clearing XN (execute-never) lets injected bytes on the heap execute; a code-injection attack could jump there. Data regions should be XN. See Buffer overflow attacks.
Why does the guard region trigger on the very first overflowing write, not later?
The MPU checks each access before it completes, so the moment the stack pointer's write lands inside the no-access guard, the CPU vectors to the fault instead of corrupting neighbouring memory.
Why must the most restrictive region get the highest number?
Because overlap ties are broken by highest number winning; if the permissive background outranked the guard, the guard's "no access" would be overridden and useless.
Why prefer an MPU over an MMU in a car ECU or pacemaker?
No page tables means fixed, low, predictable fault latency and no translation stalls — critical where a missed deadline is a safety failure, not a slowdown.
Why does XN on the stack defend against classic exploits even if the attacker fully controls stack bytes?
Overwriting a return address can point execution into the stack, but XN makes any instruction-fetch from stack addresses fault, so redirected code can't run.
Why does the MPU raise a fault instead of just returning a garbage value on a bad read?
A silent garbage value would let the bug propagate invisibly; faulting immediately hands control to MemManage_Handler so you catch the culprit task at the exact instruction.
Why re-program MPU regions on every RTOS task switch?
Each task owns a different stack and permission set; the scheduler must swap the region config so the incoming task's fences (and only its own) are enforced.
Why does a region size always have to be a power of two?
The MPU decides "is this address in the region?" by masking low bits — a test that only works cleanly when the size is 2n and the base's low n bits are zero, which is far cheaper than an arbitrary comparator.
What happens with a zero-size or size-below-32-bytes region?
It's illegal — the minimum ARM MPU region is 32 bytes (25); smaller values aren't encodable and the region simply won't protect what you intend.
What if a single access straddles two regions with different permissions?
For an aligned access this can't happen, but an unaligned access crossing a boundary is evaluated against the winning region for each part and faults if either part is denied — another reason to keep data naturally aligned.
What if PRIVDEFENA is set and a privileged task overflows into unmapped-by-region space?
The background default map lets the privileged write succeed silently — so guard regions must be explicit regions, not left to the background, or privileged overflows go undetected.
What happens to an execute access on an XN region that otherwise allows read/write?
The read/write succeed but the instruction fetch faults; XN is orthogonal to the AP data permissions, controlling only the fetch dimension of an access.
What if two guard regions and a stack region all overlap the same byte?
Only the single highest-numbered matching region's rules apply — the others are entirely ignored for that byte, so stacking guards buys nothing; number them so the strictest is highest.
Can you subregion-disable a 64-byte region to skip its middle 32 bytes?
No — each of the 8 subregions would be only 8 bytes, below the 32-byte floor, so subregion disable is unavailable for regions smaller than 256 bytes.
Recall Quick self-test
The guard wins because it has the ::: highest region number among matching regions.
A region base must align to ::: its own size (size is a power of two, low n bits zero for a 2n region).
XN (execute-never) protects against ::: executing injected code, not against the overflowing write itself.
Minimum ARM MPU region size is ::: 32 bytes (25).
MMFAR holds the ::: faulting address on a MemManage fault, with its validity flagged in MMFSR.
A region is internally split into ::: 8 equal subregions, each individually disable-able.