1、引言
為什么要談 MPU(Memory Protection Unit)?MPU 是內(nèi)核中與地址屬性設(shè)置及代碼保護(hù)相關(guān)的外設(shè)。ARM 架構(gòu)的 MCU 內(nèi)核通常有默認(rèn)的地址映射表以及各個(gè)地址段的默認(rèn)訪問屬性,當(dāng)應(yīng)用所需要的地址類型或者屬性與默認(rèn)配置不一致時(shí),往往需要針對(duì) MPU region配置某段地址區(qū)的類型和內(nèi)核的訪問屬性,其中包括設(shè)置內(nèi)核對(duì)某段地址的訪問許可,實(shí)現(xiàn)memory 的保護(hù)機(jī)制。
近年來(lái) STM32 推出了多款采用 Armv8-M 內(nèi)核的 MCU 新產(chǎn)品。Armv8-M 內(nèi)核中包含了基于 PMSAv8 (Protected Memory System Architecture)的新版本 MPU,與 v7-M 的MPU 相比,它的配置和使用都發(fā)生了不少變化。另外 Armv8-M 內(nèi)核還增加了安全擴(kuò)展(Security Extension),支持 v8-M TrustZone 架構(gòu),在 TrustZone 架構(gòu)下使用 MPU 也有特別的地方,v8-M TrustZone 架構(gòu)下的存儲(chǔ)器保護(hù)除了傳統(tǒng)的 MPU,還增加了針對(duì)安全屬性進(jìn)行配置和管理的 SAU 單元。本文將主要探討 v8-M 架構(gòu)下 MPU 的使用技巧。
2、Armv8-M 地址空間與默認(rèn)地址映射
Armv8-M 是基于地址映射的架構(gòu),Cortex-M 處理器支持 32 位的地址訪問,可以訪問最大 4GB 的地址空間。Armv8-M 架構(gòu)預(yù)定義的 32 位地址空間被劃分為代碼、數(shù)據(jù)、外設(shè)等區(qū)域,支持片內(nèi)和片外的資源,總共 8 個(gè)分區(qū),每個(gè)分區(qū)占用 0.5GB 的空間,包括:
- Code
- SRAM
- Peripheral
- 2x RAM (external)
- 2x Device (external)
- System
3、MPU (Memory Protection Unit)
MPU 是內(nèi)核外設(shè)的一個(gè)單元, Armv8-M 采用了新版的 PSMAv8 MPU。
4、MPU 使用場(chǎng)景及注意事項(xiàng)
?MPU 使用場(chǎng)景
由于 ARM 架構(gòu)已經(jīng)有默認(rèn)的地址映射表,很多時(shí)候在 MCU 中即使不使用 MPU,應(yīng)用程序也能夠正常執(zhí)行。但是在某些場(chǎng)景中配置和使用 MPU 是必要的,否則系統(tǒng)無(wú)法正常運(yùn)行,常見的情況包括:
- 代碼執(zhí)行(指令或者數(shù)據(jù))需要用到外部 Memory(Flash 或者 RAM),而外掛Memory 在系統(tǒng)中的映射地址落在默認(rèn)的 Device 類型的地址范圍:
o 這種情況需要配置 MPU region,將對(duì)應(yīng)地址范圍配置為 Normal 類型。
- 希望通過 Cache 提高代碼執(zhí)行或者數(shù)據(jù)訪問效率,但是代碼或者數(shù)據(jù)所在地址范圍在默認(rèn)的地址映射表中為 non-cacheable,或者默認(rèn)的 Cache 策略與期望的策略不一致:
o 此時(shí)需要通過 MPU region 修改相關(guān) Cache 策略配置。
- 希望對(duì)代碼執(zhí)行安全性進(jìn)行保護(hù),例如在執(zhí)行某段關(guān)鍵代碼時(shí),禁止意外跳轉(zhuǎn)到該段代碼區(qū)以外的地址執(zhí)行:
o 這種情況需要定義 MPU region 并設(shè)置關(guān)鍵代碼區(qū)以外為 XN 屬性,只允許期望的地址范圍可以做取指令訪問。
- 需要對(duì)某些資源的訪問進(jìn)行保護(hù),比如部分代碼和數(shù)據(jù)只允許特權(quán)代碼訪問:
o 這種情況需要定義 MPU region,設(shè)置對(duì)應(yīng)地址范圍的 AP 訪問控制屬性為Priv RO 或者 Priv RW。
5、TrustZone 使能環(huán)境下使用 MPU
在多數(shù) Armv8-M 內(nèi)核的 STM32 MCU 產(chǎn)品系列中,都支持安全擴(kuò)展,也就是TrustZone 架構(gòu),比如 STM32L5,STM32U5,STM32WBA,STM32H5 等系列。當(dāng)系統(tǒng)的安全擴(kuò)展處于使能狀態(tài)時(shí),即 TrustZone 使能后,內(nèi)核中在安全側(cè)和非安全側(cè)各有一套 MPU,相對(duì)于沒有啟用 TrustZone 安全擴(kuò)展的情況,這種環(huán)境下 MPU 的功能和行為會(huì)有些變化,這個(gè)小節(jié)將重點(diǎn)討論 TrustZone 環(huán)境下使用 MPU 的不同之處。
6、MemManage Fault 處理與調(diào)試技巧
?MemManage Fault 及其使能
當(dāng)系統(tǒng)中出現(xiàn)違反 MPU 保護(hù)規(guī)則的訪問時(shí),會(huì)觸發(fā) MemManage Fault 異常,異常相關(guān)信息會(huì)體現(xiàn)在 SCB CFSR 寄存器的 MMFSR 位上,如果 MMFSR 的 MMARVALID 位被置位,則 MMFAR 的內(nèi)容還會(huì)提示觸發(fā)錯(cuò)誤的訪問地址。
在 Armv8-M 的異常模型中,系統(tǒng)默認(rèn)使能的只有 HardFault,也就是說(shuō)違反 MPU 規(guī)則導(dǎo)致的異常并不會(huì)進(jìn)入軟件的 MemManage Fault Handler,而是統(tǒng)一進(jìn)入 HardFaultHandler。如果軟件希望單獨(dú)處理 MemManage Fault,則需要事先設(shè) SCB 的 SHCSR 寄存器,將 SHCSR.MEMFAULTENA 置位來(lái)使能 MemManage Fault,使能后MemManage Fault 將觸發(fā)系統(tǒng)進(jìn)入 MemManage Fault Handler 執(zhí)行。
如果開啟了 TrustZone 安全擴(kuò)展,則系統(tǒng)默認(rèn)使能的只有 Secure HardFault,即使是非安全側(cè)代碼違反 MPU 保護(hù)規(guī)則導(dǎo)致了異常,也只會(huì)進(jìn)入 Secure HardFault Handler。在 TrustZone 環(huán)境中 MemManage Fault 是 banked,也就是說(shuō)安全和非安全側(cè)可以有各自的 MemManage Fault 以及對(duì)應(yīng)的 Handler,SCB 也區(qū)分 SCB_S 和 SCB_NS,其中的 CFSR_S 和 CFSR_NS 寄存器的 MMFSR 以及 MMFAR 寄存器也會(huì)各自提示安全側(cè)和非安全側(cè)的 MemManage Fault 異常的信息。軟件可以單獨(dú)使能安全側(cè)或者非安全側(cè)的MemManage Fault,進(jìn)而各自處理自己的 MemManage Fault 異常。軟件代碼可以根據(jù) Fault 處理的需要進(jìn)行配置。
- 置位 SCB_S 的 SHCSR.MEMFAULTENA,將使能安全側(cè) MemManage Fault,錯(cuò)誤可以觸發(fā)進(jìn)入安全側(cè) MemManage Fault Handler
- 置位 SCB_NS 的 SHCSR.MEMFAULTENA,將使能非安全側(cè) MemManage Fault,錯(cuò)誤可以觸發(fā)進(jìn)入非安全側(cè) MemManage Fault Handler
- 如果沒有使能某側(cè)的 MemManage Fault,則發(fā)生錯(cuò)誤時(shí)默認(rèn)進(jìn)入 SecureHardFault Handler,使能后可以進(jìn)入該側(cè)的 MemManage Fault Handler。
這里需要說(shuō)明一點(diǎn)的是,如果某側(cè)代碼由于取對(duì)側(cè)指令違反了 MPU 規(guī)則而觸發(fā)Fault,將進(jìn)入對(duì)側(cè)的 Fault Handler,這時(shí)候是否進(jìn)入 MemManage Fault Handler,取決于對(duì)側(cè)的 SCB SHCSR.MEMFAULTENA 位的配置情況。
7、小結(jié)
本文簡(jiǎn)要介紹了 Armv8-M MPU 的功能、配置以及與 v6/v7-M MPU 相比發(fā)生的變化,舉例列舉了 v8-M MPU 的使用場(chǎng)景以及配置中的一些注意事項(xiàng),另外針對(duì)使能了Armv8-M 內(nèi)核安全擴(kuò)展(即 TrustZone)之后,MPU 功能以及使用上的變化進(jìn)行了介紹,最后分享了 MemManage 異常的處理以及一些調(diào)試技巧。
STM32 的新產(chǎn)品有越來(lái)越多的系列搭載了 Armv8-M 內(nèi)核,希望以上內(nèi)容對(duì)于開發(fā)者使用 STM32 新產(chǎn)品系列進(jìn)行開發(fā)時(shí)能有所幫助。