鴻蒙pos機,鴻蒙輕內(nèi)核的任務(wù)棧的溢出檢察官

 新聞資訊2  |   2023-06-10 09:41  |  投稿人:pos機之家

網(wǎng)上有很多關(guān)于鴻蒙pos機,鴻蒙輕內(nèi)核的任務(wù)棧的溢出檢察官的知識,也有很多人為大家解答關(guān)于鴻蒙pos機的問題,今天pos機之家(m.afbey.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、鴻蒙pos機

鴻蒙pos機

此賬號為華為云開發(fā)者社區(qū)官方運營賬號,提供全面深入的云計算前景分析、豐富的技術(shù)干貨、程序樣例,分享華為云前沿資訊動態(tài)

本文分享自華為云社區(qū)《鴻蒙輕內(nèi)核M核源碼分析系列十六 Mpu內(nèi)存保護(hù)單元》,作者: zhushy。

MPU(Memory Protection Unit,內(nèi)存保護(hù)單元)把內(nèi)存映射為一系列內(nèi)存區(qū)域,定義這些內(nèi)存區(qū)域的維洲,大小,訪問權(quán)限和內(nèi)存熟悉信息。MPU支持對每個內(nèi)存區(qū)域進(jìn)行獨立的屬性設(shè)置,允許內(nèi)存區(qū)域重,可以導(dǎo)出內(nèi)存屬性。有關(guān)MPU的詳細(xì)信息可以參考官方資料站點,比如對應(yīng)Cortex-M3的文檔位置為:https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-Memory-protection-unit。

在鴻蒙輕內(nèi)核中,MPU用于任務(wù)棧的溢出檢測。本文主要分析鴻蒙輕內(nèi)核MPU模塊的源碼。本文中所涉及的源碼,以O(shè)penHarmonyLiteOS-M內(nèi)核為例,均可以在開源站點https://gitee.com/openharmony/kernel_liteos_m 獲取。鴻蒙輕內(nèi)核支持的ARM Cortex-M芯片架構(gòu)都支持MPU的,代碼都是一樣的,以kernel\\arch\\arm\\cortex-m4\\gcc\\los_mpu.c為例進(jìn)行講解。

1、MPU枚舉、結(jié)構(gòu)體定義和常用宏定義1.1 MPU枚舉、結(jié)構(gòu)體定義

在文件kernel\\arch\\include\\los_mpu.h定義MPU相關(guān)的結(jié)構(gòu)體。⑴處定義MPU內(nèi)存區(qū)域的訪問權(quán)限,有關(guān)訪問權(quán)限可以訪問官網(wǎng)https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-access-permission-attributes,特別是上述頁面的表格Table 4.47. AP encoding了解更多。⑵處定義MPU的是否可執(zhí)行屬性枚舉,⑶處定義MPU內(nèi)存區(qū)域是否可以共享屬性枚舉,⑷定義內(nèi)存區(qū)域的類型屬性枚舉,⑸處的結(jié)構(gòu)體用于定義MPU內(nèi)存區(qū)域。

⑴ typedef enum { MPU_RW_BY_PRIVILEGED_ONLY = 0, MPU_RW_ANY = 1, MPU_RO_BY_PRIVILEGED_ONLY = 2, MPU_RO_ANY = 3, } MpuAccessPermission;⑵ typedef enum { MPU_EXECUTABLE = 0, MPU_NON_EXECUTABLE = 1, } MpuExecutable;⑶ typedef enum { MPU_NO_SHARE = 0, MPU_SHARE = 1, } MpuShareability;⑷ typedef enum { MPU_MEM_ON_CHIP_ROM = 0, MPU_MEM_ON_CHIP_RAM = 1, MPU_MEM_XIP_PSRAM = 2, MPU_MEM_XIP_NOR_FLASH = 3, MPU_MEM_SHARE_MEM = 4, } MpuMemType;⑸ typedef struct { UINT32 baseAddr; UINT64 size; /* armv7 size == 2^x (5 <= x <= 32) 128B - 4GB */ MpuAccessPermission permission; MpuExecutable executable; MpuShareability shareability; MpuMemType memType; } MPU_CFG_PARA;1.2 MPU宏

MPU外設(shè)的一些宏定義有HALDrivers定義,比如對于Cortex-M4,位置為Drivers\\CMSIS\\Core\\Include\\core_cm4.h。MPU結(jié)構(gòu)體定義如下,關(guān)于MPU寄存器的詳細(xì)信息可以訪問https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit,查看頁面上的Table 4.38. MPU registers summary。下文在講解代碼時會涉及MPU的各個寄存器。

#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */#endif

另外,MPU支持8個內(nèi)存區(qū)域,kernel\\arch\\arm\\cortex-m4\\gcc\\los_mpu.c文件中定義的宏如下:

#define MPU_MAX_REGION_NUM 82、MPU常用操作

MPU常用操作函數(shù)包含使能MPUHalMpuEnable、失能MPUHalMpuDisable,設(shè)置指定的內(nèi)存區(qū)域?qū)傩訦alMpuSetRegion,失能指定的內(nèi)存區(qū)域HalMpuDisableRegion和獲取未使用的內(nèi)存區(qū)域編號HalMpuUnusedRegionGet。

2.1 使能MPU

HalMpuEnable該函數(shù)使能MPU功能,⑴處對MPU控制寄存器MPU Control Register進(jìn)行操作,通過對寄存器相關(guān)的bit位進(jìn)行賦值來使能MPU。有關(guān)該寄存器建議詳細(xì)閱讀https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-control-register。⑵處代碼使能MemoryFault異常。接著執(zhí)行的數(shù)據(jù)同步屏障__DSB()和指令同步屏障__ISB(),詳細(xì)的可以查閱ARM的DMB,DSB,ISB等指令。

VOID HalMpuEnable(UINT32 defaultRegionEnable){ UINT32 intSave = HalIntLock();⑴ MPU->CTRL = (MPU_CTRL_ENABLE_Msk | ((defaultRegionEnable << MPU_CTRL_PRIVDEFENA_Pos) & MPU_CTRL_PRIVDEFENA_Msk));⑵ SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; __DSB(); __ISB(); HalIntRestore(intSave);}2.2 失能MPU

HalMpuDisable代碼很簡單,直接把MPU控制寄存器賦值為0來失能MPU功能。

VOID HalMpuDisable(VOID){ UINT32 intSave = HalIntLock(); MPU->CTRL = 0; __DSB(); __ISB(); HalIntRestore(intSave);}2.3 失能指定的內(nèi)存區(qū)域HalMpuDisableRegion

HalMpuDisableRegion函數(shù)執(zhí)行后不再對指定的內(nèi)存區(qū)域進(jìn)行MPU保護(hù),⑴處校驗參數(shù)合法性。⑵處沒有使用的MPU內(nèi)存區(qū)域無法失能。⑶處獲取MPU的類型寄存器,詳細(xì)可以訪問https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-type-register。

⑷處表示MPU的數(shù)據(jù)內(nèi)存區(qū)域(MPU dataregions)數(shù)量不為空時,執(zhí)行⑸處代碼更新MPU內(nèi)存區(qū)域編號寄存器(MPU Region Number Register)為指定的內(nèi)存區(qū)域編號,詳細(xì)的信息可以參考https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-region-number-register。然后執(zhí)行⑹處代碼更新MPU內(nèi)存區(qū)域?qū)傩院痛笮〖拇嫫?MPU Region Attribute andSize Register),詳細(xì)可以參考https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-region-attribute-and-size-register。⑺處把全局變量數(shù)組中指定的區(qū)域編號設(shè)置為未使用0。

UINT32 HalMpuDisableRegion(UINT32 regionId){ volatile UINT32 type; UINT32 intSave;⑴ if (regionId >= MPU_MAX_REGION_NUM) { return LOS_NOK; } intSave = HalIntLock();⑵ if (!g_regionNumBeUsed[regionId]) { HalIntRestore(intSave); return LOS_NOK; }⑶ type = MPU->TYPE;⑷ if ((MPU_TYPE_DREGION_Msk & type) != 0) {⑸ MPU->RNR = regionId;⑹ MPU->RASR = 0; __DSB(); __ISB(); }⑺ g_regionNumBeUsed[regionId] = 0; /* clear mpu region used flag */ HalIntRestore(intSave); return LOS_OK;}2.4 設(shè)置指定的內(nèi)存區(qū)域?qū)傩訦alMpuSetRegion

HalMpuSetRegion函數(shù)設(shè)置指定的內(nèi)存區(qū)域的屬性。⑴處對參數(shù)進(jìn)行合法性校驗。⑵處如果MPU類型寄存器中表示的數(shù)據(jù)內(nèi)存區(qū)域的數(shù)量為0,無法繼續(xù)設(shè)置內(nèi)嵌區(qū)域,直接返回LOS_NOK。⑶處調(diào)用函數(shù)HalMpuEncodeSize根據(jù)內(nèi)存區(qū)域的實際大小值獲取編碼大小,該值后續(xù)會被賦值給MPU屬性和大小寄存器的size位。⑷判斷內(nèi)存區(qū)域需要相對內(nèi)存區(qū)域大小進(jìn)行內(nèi)存對齊,否則返回LOS_NOK。

⑸處計算基地址寄存器的數(shù)據(jù),有關(guān)基地址寄存器(MPU Region Base AddressRegister),可以訪問https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit/mpu-region-base-address-register了解更多。⑹處計算屬性和大小寄存器的數(shù)值。⑺處如果指定的內(nèi)存區(qū)域被使用,直接返回LOS_NOK。⑻處設(shè)置MPU相關(guān)的寄存器,并標(biāo)記該內(nèi)存區(qū)域已使用。代碼如下:

UINT32 HalMpuSetRegion(UINT32 regionId, MPU_CFG_PARA *para){ UINT32 RASR; UINT32 RBAR; UINT32 RNR; UINT32 encodeSize; UINT32 intSave; UINT64 size;⑴ if ((regionId >= MPU_MAX_REGION_NUM) || (para == NULL)) { return LOS_NOK; }⑵ if ((MPU_TYPE_DREGION_Msk & MPU->TYPE) == 0) { return LOS_NOK; } RNR = regionId;⑶ encodeSize = HalMpuEncodeSize(para->size); if (encodeSize == 0) { return LOS_NOK; }⑷ size = para->size - 1; /* size aligned after encode check */ if ((para->baseAddr & size) != 0) { /* base addr should aligned to region size */ return LOS_NOK; }⑸ RBAR = para->baseAddr & MPU_RBAR_ADDR_Msk;⑹ RASR = HalMpuGetRASR(encodeSize, para); intSave = HalIntLock();⑺ if (g_regionNumBeUsed[regionId]) { HalIntRestore(intSave); return LOS_NOK; }⑻ MPU->RNR = RNR; MPU->RBAR = RBAR; MPU->RASR = RASR; __DSB(); __ISB(); g_regionNumBeUsed[regionId] = 1; /* Set mpu region used flag */ HalIntRestore(intSave); return LOS_OK;}2.4.1 HalMpuEncodeSize根據(jù)內(nèi)存區(qū)域?qū)嶋H大小獲取size屬性值

HalMpuEncodeSize函數(shù)根據(jù)內(nèi)存區(qū)域?qū)嶋H大小獲取size屬性值,對應(yīng)的計算公式為:(Regionsize in bytes) = 2^(SIZE+1),詳細(xì)信息可以訪問MPU屬性和大小寄存器官網(wǎng)資料頁面的Table 4.44. Example SIZE field values。32bytes對應(yīng)4,1KB對應(yīng)5,…,4GB對應(yīng)31。

⑴處表示內(nèi)存區(qū)域大小不能大于4GB,然后判斷是否相對32字節(jié)進(jìn)行內(nèi)存對齊。⑵處先右移2位,然后while循環(huán),執(zhí)行⑶每向右循環(huán)一位,size屬性大小增加1。

STATIC UINT32 HalMpuEncodeSize(UINT64 size){ UINT32 encodeSize = 0;⑴ if (size > SIZE_4G_BYTE) { return 0; } if ((size & 0x1F) != 0) { /* size should aligned to 32 byte at least. */ return 0; }⑵ size = (size >> 2); while (size != 0) { if (((size & 1) != 0) && ((size & 0xFFFFFFFE) != 0)) { /* size != 2^x (5 <= x <= 32) 128B - 4GB */ return 0; }⑶ size = (size >> 1); encodeSize++; } return encodeSize;}2.4.2 HalMpuGetRASR根據(jù)size屬性值和配置參數(shù)計算屬性和大小寄存器的值

HalMpuGetRASR根據(jù)size屬性值和配置參數(shù)計算屬性和大小寄存器的值。⑴處根據(jù)配置的訪問權(quán)限計算AP(ACCESS permission),然后計算屬性和大小寄存器的值,最后執(zhí)行⑶給寄存器賦值。

STATIC UINT32 HalMpuEncodeAP(MpuAccessPermission permission){ UINT32 ap; switch (permission) { case MPU_RW_BY_PRIVILEGED_ONLY: ap = MPU_AP_RW_USER_FORBID; break; case MPU_RW_ANY: ap = MPU_AP_RW_USER_RW; break; case MPU_RO_BY_PRIVILEGED_ONLY: ap = MPU_AP_RO_USER_FORBID; break; case MPU_RO_ANY: ap = MPU_AP_RO_USER_RO; break; default: ap = MPU_AP_RW_USER_RW; break; } return ap;}STATIC VOID HalMpuRASRAddMemAttr(MPU_CFG_PARA *para, UINT32 *RASR){ BOOL cachable = 0; BOOL buffable = 0; switch (para->memType) { case MPU_MEM_ON_CHIP_ROM: case MPU_MEM_ON_CHIP_RAM: cachable = 1; buffable = 0; break; case MPU_MEM_XIP_PSRAM: cachable = 1; buffable = 1; break; case MPU_MEM_XIP_NOR_FLASH: cachable = 0; buffable = 1; break; default: break; } (*RASR) |= ((cachable << MPU_RASR_C_Pos) | (buffable << MPU_RASR_B_Pos));}STATIC UINT32 HalMpuGetRASR(UINT32 encodeSize, MPU_CFG_PARA *para){ UINT32 RASR; UINT32 ap;⑴ ap = HalMpuEncodeAP(para->permission); RASR = MPU_RASR_ENABLE_Msk; RASR |= ((encodeSize << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk); RASR |= ((ap << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | ((para->executable << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | ((para->shareability << MPU_RASR_S_Pos) & MPU_RASR_S_Msk);⑶ HalMpuRASRAddMemAttr(para, &RASR); return RASR;}

點擊關(guān)注,第一時間了解華為云新鮮技術(shù)~華為云博客_大數(shù)據(jù)博客_AI博客_云計算博客_開發(fā)者中心-華為云

以上就是關(guān)于鴻蒙pos機,鴻蒙輕內(nèi)核的任務(wù)棧的溢出檢察官的知識,后面我們會繼續(xù)為大家整理關(guān)于鴻蒙pos機的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://m.afbey.com/newsone/66032.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。