Перейти к содержанию

Блок защиты памяти (MPU)

У микроконтроллера нет операционной системы с виртуальной памятью, но защитить часть памяти всё же можно. В ядрах Cortex-M для этого есть блок защиты памяти (MPU): он разрешает или запрещает обращения к заданным областям и выполнение кода из них.

Обновлено Редакция GAW

Блок защиты памяти (Memory Protection Unit, MPU) — необязательный блок ядер Arm Cortex-M, который делит карту памяти на области и для каждой задаёт права доступа и атрибуты: можно ли читать, писать, выполнять код, для привилегированного кода или для всех. Обращение в нарушение правил вызывает отказ MemManage, а если его обработчик не включён — HardFault. Виртуальной памяти, как в процессорах с MMU, у MPU нет: адреса не преобразуются, только проверяются.

Области

По руководству Arm для Cortex-M3 (разд. 4.5):

ПараметрЗначение
Число областей8 (0–7) плюс фоновая
Размер2SIZE+1 байт, от 32 байт до 4 ГБ
Базовый адресвыровнен на размер области
Подобласти8 на область, у областей 128 байт и меньше нет
Перекрытиедействует область с большим номером

Фоновая область повторяет атрибуты стандартной карты памяти, но доступна только привилегированному коду. Бит XN запрещает выполнение кода из области — так защищают ОЗУ и периферию от случайного перехода туда.

размер=2SIZE+1 байт,SIZE=4⇒32 байта.\text{размер} = 2^{SIZE+1}\ \text{байт}, \qquad SIZE = 4 \Rightarrow 32\ \text{байта}.

Зачем в прошивке

  • Защита от переполнения стека. Маленькая область без прав доступа под нижней границей стека превращает тихую порчу данных в немедленный отказ.
  • Запрет выполнения из ОЗУ — от ошибок с указателями на функции.
  • Изоляция задач в ОС реального времени — ядро ОС перенастраивает области при переключении задач.

Не путать MPU с датчиком MPU-6050 (это название линейки датчиков движения) и с MMU — блоком виртуальной памяти в процессорах приложений. Карта памяти Cortex-M3 и исключения — в статье «Архитектура ARM Cortex-M3», границы областей памяти в прошивке задаёт скрипт компоновщика.

Частые вопросы

Есть ли MPU во всех STM32?

Нет: в Cortex-M3 и M4 MPU — необязательный блок, и производитель решает, ставить ли его. Наличие и число областей можно узнать из регистра MPU_TYPE: если поле DREGION равно нулю, блока нет. Например, у STM32F103 MPU нет: в его заголовке CMSIS `__MPU_PRESENT = 0`. Точный ответ для конкретной серии даёт её даташит или руководство программиста.

Можно ли с помощью MPU поймать переполнение стека?

Да: под нижней границей стека делают маленькую область без прав доступа. Когда стек переполняется и залезает в неё, вместо тихой порчи данных возникает отказ MemManage (или HardFault, если обработчик не включён), и ошибку видно сразу. Наименьшая область у Cortex-M3 — 32 байта, адрес должен быть выровнен на её размер.

Почему размер области MPU — степень двойки?

Так устроен регистр MPU_RASR: размер задаётся полем SIZE как 2^(SIZE+1) байт, от 32 байт до 4 ГБ, а базовый адрес должен быть выровнен на этот размер. Для более точной настройки область делится на 8 подобластей, которые можно отключать по отдельности.

Источники

  1. Arm. Cortex-M3 Devices Generic User Guide, DUI 0552A, 2010 — разд. 4.5: MPU необязателен; делит карту памяти на области с адресом, размером, правами и атрибутами; у Cortex-M3 8 областей (0–7) и фоновая область, доступная только привилегированному коду; при перекрытии действует область с большим номером; запрещённое обращение вызывает отказ MemManage; табл. 4-43: размер области 2^(SIZE+1) байт, наименьший 32 байта, наибольший 4 ГБ; базовый адрес выровнен на размер области; 8 подобластей, у областей 128 байт и меньше их нет; бит XN запрещает выборку команд
  2. Arm. ARMv7-M Architecture Reference Manual, DDI 0403E.e, 2021 — архитектура защищённой системы памяти PMSAv7, регистры MPU_TYPE, MPU_CTRL, MPU_RNR, MPU_RBAR, MPU_RASR

Нашли ошибку?