MPU(Memory Protection Unit,內(nèi)存保護(hù)單元)在 Cortex-M內(nèi)核中是可選模塊,帶MPU的微控制器允許內(nèi)存映射(包括Flash、RAM和外圍設(shè)備)細(xì)分為若干區(qū)域,分別給每個(gè)區(qū)域分配不同的訪問權(quán)限。
FreeRTOS-MPU是FreeRTOS針對(duì)MPU實(shí)現(xiàn)的一個(gè)安全版本,支持ARMv7-M(Cortex-M3, Cortex-M4 和 Cortex-M7)和ARMv8-M (Cortex-M23和Cortex-M33)內(nèi)核的微控制器。 針對(duì)ARMv7-M的FreeRTOS移植存在兩個(gè)版本,一個(gè)支持MPU,一個(gè)不支持。針對(duì)ARMv8-M只有一個(gè)移植版本,通過編譯開關(guān)控制是否支持MPU。 FreeRTOS通過將任務(wù)分為特權(quán)和非特權(quán)運(yùn)行模式和限制對(duì)RAM、外設(shè)、可執(zhí)行代碼、任務(wù)堆棧內(nèi)存的訪問,使得應(yīng)用更健壯和安全。例如,防止代碼從RAM中執(zhí)行可以獲得巨大的好處,因?yàn)檫@樣做可以防止許多攻擊向量,如緩沖區(qū)溢出漏洞或加載到RAM中的惡意代碼的執(zhí)行。 使用MPU必然會(huì)使應(yīng)用程序設(shè)計(jì)更加復(fù)雜,首先必須確定MPU的內(nèi)存區(qū)域限制并向RTOS進(jìn)行描述,其次MPU限制應(yīng)用程序任務(wù)可以做什么和不能做什么。MPU的策略
創(chuàng)建一個(gè)將每個(gè)任務(wù)限制在其自己的內(nèi)存區(qū)域的應(yīng)用程序可能是最安全的,但它也是設(shè)計(jì)和實(shí)現(xiàn)最復(fù)雜的。通常最好使用一個(gè)MPU來創(chuàng)建一個(gè)偽進(jìn)程和線程模型——允許線程組共享內(nèi)存空間。例如,創(chuàng)建一個(gè)可被可信的第一方代碼訪問的內(nèi)存空間,以及一個(gè)僅可被不可信的第三方代碼訪問的內(nèi)存空間。
FreeRTOS-MPU特性
兼容ARM Cortex-M3和Cortex-M4F標(biāo)準(zhǔn)移植。
可以創(chuàng)建以特權(quán)模式或非特權(quán)模式運(yùn)行的任務(wù)。非特權(quán)任務(wù)只能訪問它們自己的堆棧和最多三個(gè)用戶可定義的內(nèi)存區(qū)域(每個(gè)任務(wù)三個(gè))。用戶可定義內(nèi)存區(qū)域是在創(chuàng)建任務(wù)時(shí)分配給任務(wù)的,如果需要,可以在運(yùn)行時(shí)重新配置。
用戶可定義的內(nèi)存區(qū)域可以單獨(dú)參數(shù)化。例如,一些區(qū)域可能被設(shè)置為只讀,而另一些區(qū)域可能被設(shè)置為不可執(zhí)行(在ARM術(shù)語中簡(jiǎn)稱為XN),等等。
非特權(quán)任務(wù)之間不共享數(shù)據(jù)內(nèi)存,但非特權(quán)任務(wù)可以使用標(biāo)準(zhǔn)隊(duì)列和信號(hào)量機(jī)制相互傳遞消息。可以通過使用用戶可定義的內(nèi)存區(qū)域顯式地創(chuàng)建共享內(nèi)存區(qū)域,但是不建議這樣做。
特權(quán)模式任務(wù)可以將自己設(shè)置為非特權(quán)模式,但一旦進(jìn)入非特權(quán)模式,它就不能再將自己設(shè)置為特權(quán)模式。
FreeRTOS API位于Flash的一個(gè)區(qū)域,該區(qū)域只能在微控制器處于特權(quán)模式(調(diào)用API函數(shù)導(dǎo)致臨時(shí)切換到特權(quán)模式)時(shí)訪問。
內(nèi)核維護(hù)的數(shù)據(jù)位于RAM的一個(gè)區(qū)域,只有在微控制器處于特權(quán)模式時(shí)才能訪問。
系統(tǒng)外設(shè)只能在微控制器處于特權(quán)模式時(shí)訪問。任何代碼都可以訪問標(biāo)準(zhǔn)外設(shè)(UART等),但是可以使用可定義的內(nèi)存區(qū)域顯式地對(duì)其進(jìn)行保護(hù)。
FreeRTOS-MPU可以創(chuàng)建兩種類型的任務(wù):
特權(quán)任務(wù):特權(quán)任務(wù)可以訪問整個(gè)內(nèi)存映射。特權(quán)任務(wù)可以使用xTaskCreate()或xTaskCreateRestricted() API函數(shù)來創(chuàng)建。
非特權(quán)任務(wù):非特權(quán)任務(wù)只能訪問它的堆棧。此外,可以授予它最多三個(gè)用戶可定義內(nèi)存區(qū)域的訪問權(quán)限(每個(gè)任務(wù)三個(gè))。非特權(quán)任務(wù)只能使用xTaskCreateRestricted()創(chuàng)建。注意,xTaskCreate()不能用于創(chuàng)建非特權(quán)任務(wù)。
如果一個(gè)任務(wù)想要使用MPU,那么必須提供以下附加信息:
任務(wù)堆棧的地址。
最多三個(gè)用戶可定義內(nèi)存區(qū)域的開始、大小和訪問參數(shù)。
因此,創(chuàng)建任務(wù)所需的參數(shù)總數(shù)非常大。為了使創(chuàng)建MPU任務(wù)更容易, xTaskCreateRestricted()使用了一個(gè)名為xTaskParameters的參數(shù)結(jié)構(gòu)體,通常定義為結(jié)構(gòu)常量存儲(chǔ)在Flash中,并將該結(jié)構(gòu)地址作為單個(gè)參數(shù)傳遞給xTaskCreateRestricted()。
typedef struct xTASK_PARAMTERS
{
TaskFunction_t pvTaskCode;
const signed char * const pcName;
unsigned short usStackDepth;
void * pvParameters;
UBaseType_t uxPriority;
portSTACK_TYPE * puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
} TaskParameters_t;
typedef struct xMEMORY_REGION
{
void *pvBaseAddress; /* 起始地址 */
unsigned long ulLengthInBytes; /* 長(zhǎng)度 */
unsigned long ulParameters; /* 訪問屬性 */
} MemoryRegion_t;
分配給任務(wù)的內(nèi)存區(qū)域可以使用vTaskAllocateMPURegions()來更改。
預(yù)定義區(qū)域和用戶可定義區(qū)域
區(qū)域0~4被內(nèi)核配置為可用的運(yùn)行環(huán)境,其中:
運(yùn)行狀態(tài)的任務(wù)可以訪問它自己的棧,但是所有其他的RAM只有當(dāng)運(yùn)行在特權(quán)模式時(shí)才可以訪問。
只有當(dāng)在特權(quán)模式下運(yùn)行時(shí),才能訪問內(nèi)核和系統(tǒng)外設(shè)所在的Flash內(nèi)存區(qū)域。
Flash內(nèi)存(除了內(nèi)核所在的內(nèi)存)和所有非系統(tǒng)外設(shè)(例如UART和模擬輸入)都可以被特權(quán)和用戶模式任務(wù)訪問。
內(nèi)核在每次上下文切換期間都會(huì)重新配置MPU,因此每個(gè)任務(wù)可以不同地定義其余三個(gè)區(qū)域。
區(qū)域起始地址和大小限制
MPU硬件強(qiáng)加了兩個(gè)規(guī)則,區(qū)域起始地址和大小定義必須遵守:
1、區(qū)域大小必須是32字節(jié)到4G(包括)之間的二進(jìn)制的2次方。例如,32字節(jié)、64字節(jié)、128字節(jié)、256字節(jié)等等都是有效的區(qū)域大小。
2、起始地址必須是區(qū)域大小的倍數(shù)。例如,一個(gè)配置為65536字節(jié)長(zhǎng)的區(qū)域必須從能被65536整除的地址開始。
FreeRTOS-MPUAPI
1、xTaskCreateRestricted()是xTaskCreate()的擴(kuò)展版本,用于創(chuàng)建執(zhí)行權(quán)限受限或者內(nèi)存訪問權(quán)限受限的任務(wù)。
xTaskCreateRestricted()需要xTaskCreate()使用的所有參數(shù),加上四個(gè)額外的參數(shù)來定義三個(gè)任務(wù)特定的MPU區(qū)域和一個(gè)堆棧緩沖區(qū)。如果在普通函數(shù)參數(shù)列表中使用這個(gè)數(shù)量的參數(shù)會(huì)很麻煩,而且可能會(huì)大量使用堆棧空間。xTaskCreateRestricted()將一個(gè)指向xTaskParameters結(jié)構(gòu)的指針作為其兩個(gè)參數(shù)之一,第二個(gè)參數(shù)用于向創(chuàng)建的任務(wù)傳遞句柄,與xTaskCreate()參數(shù)相同。如果不需要任務(wù)句柄, pxCreatedTask可以設(shè)置為NULL。
portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition,
xTaskHandle *pxCreatedTask );
2、vTaskAllocateMPURegions()定義一組內(nèi)存保護(hù)單元(MPU)區(qū)域,供受MPU限制的任務(wù)使用。如果創(chuàng)建任務(wù)時(shí)沒有分配MPU區(qū)域,可以在運(yùn)行時(shí)使用vTaskAllocateMPURegions()函數(shù)重新分配。
void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
const MemoryRegion_t * const xRegions );
3、特權(quán)模式任務(wù)可以調(diào)用portSWITCH_TO_USER_MODE()將自己設(shè)置為非特權(quán)模式。在非特權(quán)模式下運(yùn)行的任務(wù)不能設(shè)置為特權(quán)模式。
原文標(biāo)題:FreeRTOS MPU使系統(tǒng)更健壯!
文章出處:【微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
微控制器
+關(guān)注
關(guān)注
48文章
7649瀏覽量
152107 -
MPU
+關(guān)注
關(guān)注
0文章
375瀏覽量
48949 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62395 -
Cortex-M3
+關(guān)注
關(guān)注
9文章
270瀏覽量
59589
原文標(biāo)題:FreeRTOS MPU使系統(tǒng)更健壯!
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論