鴻蒙輕內(nèi)核A核源碼分析系列五 虛實(shí)映射(4)
鴻蒙輕內(nèi)核A核源碼分析系列五 虛實(shí)映射(4)
7、Flag標(biāo)簽屬性
在學(xué)習(xí)函數(shù)LOS_ArchMmuMap()代碼時(shí),我們已經(jīng)了解了虛擬內(nèi)存如何映射到物理內(nèi)存,在映射的時(shí)候,可以通過(guò)UINT 32 flags參數(shù)定一些標(biāo)簽屬性信息。本節(jié),我們具體了解下內(nèi)存標(biāo)簽屬性信息。先了解下MMU標(biāo)簽屬性,然后看看映射內(nèi)存區(qū)間時(shí)的映射虛實(shí)信息,最后了解下屬性信息轉(zhuǎn)換函數(shù)。
7.1 MMU標(biāo)簽屬性
在映射的時(shí)候,對(duì)于內(nèi)存頁(yè)可以指定一些內(nèi)存屬性,比如權(quán)限、內(nèi)存類型、緩存策略等等。更多信息參考ARM官網(wǎng)資料《ARM? Cortex?-A Series Version: 4.0 Programmer’s Guide》,我們只快速摘錄些關(guān)鍵信息。L1頁(yè)表項(xiàng)的格式如下圖所示,其中Type extension (TEX), Shareable (S), Access Permission (AP, APX)、 Cacheable (C)、 Bufferable (B)位表示內(nèi)存屬性信息。在arch\arm\arm\include\los_mmu_descriptor_v6.h文件中定義了MMU L1頁(yè)表內(nèi)存屬性相關(guān)的宏,如下。
/* TEX CB */ #define MMU_DESCRIPTOR_L1_TEX_SHIFT 12 /* type extension field shift */ #define MMU_DESCRIPTOR_L1_TEX(x) \ ((x) << MMU_DESCRIPTOR_L1_TEX_SHIFT) /* type extension */ #define MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE) #define MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) #define MMU_DESCRIPTOR_L1_TEX_TYPE_MASK \ (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) #define MMU_DESCRIPTOR_L1_AP2_SHIFT 15 #define MMU_DESCRIPTOR_L1_AP2(x) ((x) << MMU_DESCRIPTOR_L1_AP2_SHIFT) #define MMU_DESCRIPTOR_L1_AP2_0 (MMU_DESCRIPTOR_L1_AP2(0)) #define MMU_DESCRIPTOR_L1_AP2_1 (MMU_DESCRIPTOR_L1_AP2(1)) #define MMU_DESCRIPTOR_L1_AP01_SHIFT 10 #define MMU_DESCRIPTOR_L1_AP01(x) ((x) << MMU_DESCRIPTOR_L1_AP01_SHIFT) #define MMU_DESCRIPTOR_L1_AP01_0 (MMU_DESCRIPTOR_L1_AP01(0)) #define MMU_DESCRIPTOR_L1_AP01_1 (MMU_DESCRIPTOR_L1_AP01(1)) #define MMU_DESCRIPTOR_L1_AP01_3 (MMU_DESCRIPTOR_L1_AP01(3)) #define MMU_DESCRIPTOR_L1_AP_P_NA_U_NA (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_0) #define MMU_DESCRIPTOR_L1_AP_P_RW_U_RW (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_3) #define MMU_DESCRIPTOR_L1_AP_P_RW_U_NA (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_1) #define MMU_DESCRIPTOR_L1_AP_P_RO_U_RO (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_3) #define MMU_DESCRIPTOR_L1_AP_P_RO_U_NA (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_1) #define MMU_DESCRIPTOR_L1_AP_MASK (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_3)
L2頁(yè)表項(xiàng)的格式如下圖所示。在arch\arm\arm\include\los_mmu_descriptor_v6.h文件中定義了MMU L2頁(yè)表內(nèi)存屬性相關(guān)的宏,如下。
#define MMU_DESCRIPTOR_L2_TEX_SHIFT 6 /* type extension field shift */ #define MMU_DESCRIPTOR_L2_TEX(x) \ ((x) << MMU_DESCRIPTOR_L2_TEX_SHIFT) /* type extension */ #define MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE) #define MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE) #define MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) #define MMU_DESCRIPTOR_L2_TEX_TYPE_MASK \ (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE) #define MMU_DESCRIPTOR_L2_AP2_SHIFT 9 #define MMU_DESCRIPTOR_L2_AP2(x) ((x) << MMU_DESCRIPTOR_L2_AP2_SHIFT) #define MMU_DESCRIPTOR_L2_AP2_0 (MMU_DESCRIPTOR_L2_AP2(0)) #define MMU_DESCRIPTOR_L2_AP2_1 (MMU_DESCRIPTOR_L2_AP2(1)) #define MMU_DESCRIPTOR_L2_AP01_SHIFT 4 #define MMU_DESCRIPTOR_L2_AP01(x) ((x) << MMU_DESCRIPTOR_L2_AP01_SHIFT) #define MMU_DESCRIPTOR_L2_AP01_0 (MMU_DESCRIPTOR_L2_AP01(0)) #define MMU_DESCRIPTOR_L2_AP01_1 (MMU_DESCRIPTOR_L2_AP01(1)) #define MMU_DESCRIPTOR_L2_AP01_3 (MMU_DESCRIPTOR_L2_AP01(3)) #define MMU_DESCRIPTOR_L2_AP_P_NA_U_NA (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_0) #define MMU_DESCRIPTOR_L2_AP_P_RW_U_RW (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_3) #define MMU_DESCRIPTOR_L2_AP_P_RW_U_NA (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_1) #define MMU_DESCRIPTOR_L2_AP_P_RO_U_RO (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_3) #define MMU_DESCRIPTOR_L2_AP_P_RO_U_NA (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_1) #define MMU_DESCRIPTOR_L2_AP_MASK (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_3)
7.2 映射地址區(qū)間標(biāo)簽屬性
kernel\base\include\los_vm_map.h文件中定義地址區(qū)間映射標(biāo)簽屬性信息。標(biāo)簽屬性信息主要分為4類,如圖所示。前2位用于標(biāo)記釋放緩存設(shè)備,2-5位用于標(biāo)記權(quán)限信息,6-8位用于標(biāo)記共享私有等信息,9-19位用于標(biāo)記stack、heap、data、text、bss、vsdo、mmap、shm、fixed、fixed_noreplace等屬性信息。20-23位暫未使用,高8位被共享內(nèi)存SHM使用。
/* the high 8 bits(24~31) should reserved, shm will use it */ #define VM_MAP_REGION_FLAG_CACHED (0<<0) #define VM_MAP_REGION_FLAG_UNCACHED (1<<0) #define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0) /* only exists on some arches, otherwise UNCACHED */ #define VM_MAP_REGION_FLAG_STRONGLY_ORDERED (3<<0) /* only exists on some arches, otherwise UNCACHED */ #define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0) #define VM_MAP_REGION_FLAG_PERM_USER (1<<2) #define VM_MAP_REGION_FLAG_PERM_READ (1<<3) #define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4) #define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5) #define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2) #define VM_MAP_REGION_FLAG_NS (1<<6) /* NON-SECURE */ #define VM_MAP_REGION_FLAG_SHARED (1<<7) #define VM_MAP_REGION_FLAG_PRIVATE (1<<8) #define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7) #define VM_MAP_REGION_FLAG_STACK (1<<9) #define VM_MAP_REGION_FLAG_HEAP (1<<10) #define VM_MAP_REGION_FLAG_DATA (1<<11) #define VM_MAP_REGION_FLAG_TEXT (1<<12) #define VM_MAP_REGION_FLAG_BSS (1<<13) #define VM_MAP_REGION_FLAG_VDSO (1<<14) #define VM_MAP_REGION_FLAG_MMAP (1<<15) #define VM_MAP_REGION_FLAG_SHM (1<<16) #define VM_MAP_REGION_FLAG_FIXED (1<<17) #define VM_MAP_REGION_FLAG_FIXED_NOREPLACE (1<<18) #define VM_MAP_REGION_FLAG_INVALID (1<<19) /* indicates that flags are not specified */
7.3 標(biāo)簽轉(zhuǎn)換操作
7.3.1 OsCvtProtFlagsToRegionFlags函數(shù)
函數(shù)OsCvtProtFlagsToRegionFlags()把保護(hù)屬性轉(zhuǎn)換為虛擬內(nèi)存區(qū)間標(biāo)簽屬性,該函數(shù)在系統(tǒng)調(diào)用、共享內(nèi)存等模塊會(huì)使用。參數(shù)unsigned long prot中的保護(hù)標(biāo)簽屬性如PROT_READ、MAP_SHARED等等,定義在文件third_party/musl/porting/liteos_a/kernel/include/sys/mman.h。
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags) { UINT32 regionFlags = 0; regionFlags |= VM_MAP_REGION_FLAG_PERM_USER; regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0; regionFlags |= (prot & PROT_WRITE) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0; regionFlags |= (prot & PROT_EXEC) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE) : 0; regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0; regionFlags |= (flags & MAP_PRIVATE) ? VM_MAP_REGION_FLAG_PRIVATE : 0; regionFlags |= (flags & MAP_FIXED) ? VM_MAP_REGION_FLAG_FIXED : 0; regionFlags |= (flags & MAP_FIXED_NOREPLACE) ? VM_MAP_REGION_FLAG_FIXED_NOREPLACE : 0; return regionFlags; }
7.3.2 OsCvtSecFlagsToAttrs函數(shù)和OsCvtSecAttsToFlags函數(shù)
OsCvtSecFlagsToAttrs函數(shù)用于把內(nèi)存區(qū)域映射標(biāo)簽屬性轉(zhuǎn)換為L(zhǎng)1 Section類型頁(yè)表項(xiàng)的MMU標(biāo)簽屬性。該函數(shù)又分為2個(gè)函數(shù),分別是⑴處的OsCvtSecCacheFlagsToMMUFlags()函數(shù)和⑵處的OsCvtSecAccessFlagsToMMUFlags()函數(shù)。OsCvtSecCacheFlagsToMMUFlags()函數(shù)主要判斷內(nèi)存映射區(qū)域的低2位緩存標(biāo)簽屬性的轉(zhuǎn)換。OsCvtSecAccessFlagsToMMUFlags()函數(shù)用于映射標(biāo)簽屬性的2-4位訪問(wèn)權(quán)限部分的轉(zhuǎn)換。代碼比較簡(jiǎn)單不再贅述。
⑶處的函數(shù)OsCvtSecAttsToFlags()是上述函數(shù)OsCvtSecFlagsToAttrs的逆過(guò)程,用于把L1 Section類型頁(yè)表項(xiàng)的MMU標(biāo)簽屬性轉(zhuǎn)換為內(nèi)存區(qū)域映射標(biāo)簽屬性。自行閱讀代碼,不再逐行分析。
⑴ STATIC UINT32 OsCvtSecCacheFlagsToMMUFlags(UINT32 flags) { UINT32 mmuFlags = 0; switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) { case VM_MAP_REGION_FLAG_CACHED: mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE; #ifdef LOSCFG_KERNEL_SMP mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_SHAREABLE; #endif break; case VM_MAP_REGION_FLAG_STRONGLY_ORDERED: mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED; break; case VM_MAP_REGION_FLAG_UNCACHED: mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE; break; case VM_MAP_REGION_FLAG_UNCACHED_DEVICE: mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED; break; default: return LOS_ERRNO_VM_INVALID_ARGS; } return mmuFlags; } ⑵ STATIC UINT32 OsCvtSecAccessFlagsToMMUFlags(UINT32 flags) { UINT32 mmuFlags = 0; switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) { case 0: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA; break; case VM_MAP_REGION_FLAG_PERM_READ: case VM_MAP_REGION_FLAG_PERM_USER: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_NA; break; case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_RO; break; case VM_MAP_REGION_FLAG_PERM_WRITE: case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_NA; break; case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE: case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_RW; break; default: break; } return mmuFlags; } /* convert user level mmu flags to L1 descriptors flags */ STATIC UINT32 OsCvtSecFlagsToAttrs(UINT32 flags) { UINT32 mmuFlags; mmuFlags = OsCvtSecCacheFlagsToMMUFlags(flags); if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) { return mmuFlags; } mmuFlags |= MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT; mmuFlags |= OsCvtSecAccessFlagsToMMUFlags(flags); if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_XN; } if (flags & VM_MAP_REGION_FLAG_NS) { mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_SECURE; } if (flags & VM_MAP_REGION_FLAG_PERM_USER) { mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_GLOBAL; } return mmuFlags; } ⑶ STATIC VOID OsCvtSecAttsToFlags(PTE_T l1Entry, UINT32 *flags) { *flags = 0; if (l1Entry & MMU_DESCRIPTOR_L1_SECTION_NON_SECURE) { *flags |= VM_MAP_REGION_FLAG_NS; } switch (l1Entry & MMU_DESCRIPTOR_L1_TEX_TYPE_MASK) { case MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED: *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED; break; case MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE: *flags |= VM_MAP_REGION_FLAG_UNCACHED; break; case MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED: case MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED: *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE; break; default: break; } *flags |= VM_MAP_REGION_FLAG_PERM_READ; switch (l1Entry & MMU_DESCRIPTOR_L1_AP_MASK) { case MMU_DESCRIPTOR_L1_AP_P_RO_U_NA: break; case MMU_DESCRIPTOR_L1_AP_P_RW_U_NA: *flags |= VM_MAP_REGION_FLAG_PERM_WRITE; break; case MMU_DESCRIPTOR_L1_AP_P_RO_U_RO: *flags |= VM_MAP_REGION_FLAG_PERM_USER; break; case MMU_DESCRIPTOR_L1_AP_P_RW_U_RW: *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE; break; default: break; } if (!(l1Entry & MMU_DESCRIPTOR_L1_SECTION_XN)) { *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE; } }
7.3.3 OsCvtPte2FlagsToAttrs函數(shù)和OsCvtPte2AttsToFlags函數(shù)
和上一小節(jié)非常類似,上節(jié)是L1 Section類型頁(yè)表項(xiàng)MMU屬性和內(nèi)存區(qū)域標(biāo)簽屬性的相互轉(zhuǎn)換,本節(jié)的2個(gè)函數(shù)是L2頁(yè)表項(xiàng)MMU屬性和內(nèi)存區(qū)域標(biāo)簽屬性的相互轉(zhuǎn)換。函數(shù)OsCvtPte2FlagsToAttrs()把內(nèi)存區(qū)域映射標(biāo)簽屬性轉(zhuǎn)換為L(zhǎng)2頁(yè)表項(xiàng)MMU屬性,又分為2個(gè)函數(shù),分別是⑴處的函數(shù)OsCvtPte2CacheFlagsToMMUFlags()和⑵處的OsCvtPte2AccessFlagsToMMUFlags()。OsCvtPte2CacheFlagsToMMUFlags()函數(shù)主要判斷內(nèi)存映射區(qū)域的低2位緩存標(biāo)簽屬性的轉(zhuǎn)換。OsCvtPte2AccessFlagsToMMUFlags()函數(shù)用于映射標(biāo)簽屬性的2-4位訪問(wèn)權(quán)限部分的轉(zhuǎn)換。代碼比較簡(jiǎn)單不再贅述。
⑶處的函數(shù)OsCvtPte2AttsToFlags()是上述函數(shù)OsCvtPte2FlagsToAttrs的逆過(guò)程,用于把L2頁(yè)表項(xiàng)的MMU標(biāo)簽屬性轉(zhuǎn)換為內(nèi)存區(qū)域映射標(biāo)簽屬性。自行閱讀代碼,不再逐行分析。
⑴ STATIC UINT32 OsCvtPte2CacheFlagsToMMUFlags(UINT32 flags) { UINT32 mmuFlags = 0; switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) { case VM_MAP_REGION_FLAG_CACHED: #ifdef LOSCFG_KERNEL_SMP mmuFlags |= MMU_DESCRIPTOR_L2_SHAREABLE; #endif mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE; break; case VM_MAP_REGION_FLAG_STRONGLY_ORDERED: mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED; break; case VM_MAP_REGION_FLAG_UNCACHED: mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE; break; case VM_MAP_REGION_FLAG_UNCACHED_DEVICE: mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED; break; default: return LOS_ERRNO_VM_INVALID_ARGS; } return mmuFlags; } ⑵ STATIC UINT32 OsCvtPte2AccessFlagsToMMUFlags(UINT32 flags) { UINT32 mmuFlags = 0; switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) { case 0: mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA; break; case VM_MAP_REGION_FLAG_PERM_READ: case VM_MAP_REGION_FLAG_PERM_USER: mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_NA; break; case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ: mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_RO; break; case VM_MAP_REGION_FLAG_PERM_WRITE: case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_NA; break; case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE: case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE: mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_RW; break; default: break; } return mmuFlags; } /* convert user level mmu flags to L2 descriptors flags */ STATIC UINT32 OsCvtPte2FlagsToAttrs(UINT32 flags) { UINT32 mmuFlags; mmuFlags = OsCvtPte2CacheFlagsToMMUFlags(flags); if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) { return mmuFlags; } mmuFlags |= OsCvtPte2AccessFlagsToMMUFlags(flags); if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) { mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN; } else { mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE; } if (flags & VM_MAP_REGION_FLAG_PERM_USER) { mmuFlags |= MMU_DESCRIPTOR_L2_NON_GLOBAL; } return mmuFlags; } ⑶ STATIC VOID OsCvtPte2AttsToFlags(PTE_T l1Entry, PTE_T l2Entry, UINT32 *flags) { *flags = 0; /* NS flag is only present on L1 entry */ if (l1Entry & MMU_DESCRIPTOR_L1_PAGETABLE_NON_SECURE) { *flags |= VM_MAP_REGION_FLAG_NS; } switch (l2Entry & MMU_DESCRIPTOR_L2_TEX_TYPE_MASK) { case MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED: *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED; break; case MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE: *flags |= VM_MAP_REGION_FLAG_UNCACHED; break; case MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED: case MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED: *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE; break; default: break; } *flags |= VM_MAP_REGION_FLAG_PERM_READ; switch (l2Entry & MMU_DESCRIPTOR_L2_AP_MASK) { case MMU_DESCRIPTOR_L2_AP_P_RO_U_NA: break; case MMU_DESCRIPTOR_L2_AP_P_RW_U_NA: *flags |= VM_MAP_REGION_FLAG_PERM_WRITE; break; case MMU_DESCRIPTOR_L2_AP_P_RO_U_RO: *flags |= VM_MAP_REGION_FLAG_PERM_USER; break; case MMU_DESCRIPTOR_L2_AP_P_RW_U_RW: *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE; break; default: break; } if ((l2Entry & MMU_DESCRIPTOR_L2_TYPE_MASK) != MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN) { *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE; } }
IoT 虛擬化 輕量級(jí)操作系統(tǒng) LiteOS
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。