鸿蒙轻内核A核源码分析系列五 虚实映射(7)虚实映射Flag属性

往期知识点记录:

  • 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
  • 轻内核A核源码分析系列一 数据结构-双向循环链表
  • 轻内核A核源码分析系列二 数据结构-位图操作
  • 轻内核A核源码分析系列三 物理内存(1)
  • 轻内核A核源码分析系列三 物理内存(2)
  • 轻内核A核源码分析系列四(1)虚拟内存进程空间编号
  • 轻内核A核源码分析系列四(2) 虚拟内存
  • 轻内核A核源码分析系列四(3) 虚拟内存
  • 轻内核A核源码分析系列五 虚实映射(1)基础概念
  • 轻内核A核源码分析系列五 虚实映射(2)虚实映射初始化
  • 轻内核A核源码分析系列五 虚实映射(3)虚拟物理内存映射
  • 轻内核A核源码分析系列五 虚实映射(5)虚实映射解除
  • 轻内核A核源码分析系列五 虚实映射(6)虚拟映射修改转移
  • 轻内核A核源码分析系列五 虚实映射(7)虚实映射Flag属性
  • 轻内核A核源码分析系列六 MMU协处理器(1)
  • 轻内核A核源码分析系列六 MMU协处理器(2)
  • 轻内核A核源码分析系列七 进程管理 (1)
  • 轻内核A核源码分析系列七 进程管理 (2)
  • 轻内核A核源码分析系列七 进程管理 (3)
  • 持续更新中……

在学习函数LOS_ArchMmuMap()代码时,我们已经了解了虚拟内存如何映射到物理内存,在映射的时候,可以通过UINT 32 flags参数定一些标签属性信息。本节,我们具体了解下内存标签属性信息。先了解下MMU标签属性,然后看看映射内存区间时的映射虚实信息,最后了解下属性信息转换函数。

7.1 MMU标签属性

在映射的时候,对于内存页可以指定一些内存属性,比如权限、内存类型、缓存策略等等。更多信息参考ARM官网资料《ARM® Cortex™-A Series Version: 4.0 Programmer’s Guide》,我们只快速摘录些关键信息。L1页表项的格式如下图所示,其中Type extension (TEX)Shareable (S)Access Permission (AP, APX)、 Cacheable (C)、 Bufferable (B)位表示内存属性信息。在arch\arm\arm\include\los_mmu_descriptor_v6.h文件中定义了MMU L1页表内存属性相关的宏,如下。

/* 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页表项的格式如下图所示。在arch\arm\arm\include\los_mmu_descriptor_v6.h文件中定义了MMU L2页表内存属性相关的宏,如下。

#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 映射地址区间标签属性

kernel\base\include\los_vm_map.h文件中定义地址区间映射标签属性信息。标签属性信息主要分为4类,如图所示。前2位用于标记释放缓存设备,2-5位用于标记权限信息,6-8位用于标记共享私有等信息,9-19位用于标记stack、heap、data、text、bss、vsdo、mmap、shm、fixed、fixed_noreplace等属性信息。20-23位暂未使用,高8位被共享内存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 标签转换操作

7.3.1 OsCvtProtFlagsToRegionFlags函数

函数OsCvtProtFlagsToRegionFlags()把保护属性转换为虚拟内存区间标签属性,该函数在系统调用、共享内存等模块会使用。参数unsigned long prot中的保护标签属性如PROT_READMAP_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函数和OsCvtSecAttsToFlags函数

OsCvtSecFlagsToAttrs函数用于把内存区域映射标签属性转换为L1 Section类型页表项的MMU标签属性。该函数又分为2个函数,分别是⑴处的OsCvtSecCacheFlagsToMMUFlags()函数和⑵处的OsCvtSecAccessFlagsToMMUFlags()函数。OsCvtSecCacheFlagsToMMUFlags()函数主要判断内存映射区域的低2位缓存标签属性的转换。OsCvtSecAccessFlagsToMMUFlags()函数用于映射标签属性的2-4位访问权限部分的转换。代码比较简单不再赘述。

⑶处的函数OsCvtSecAttsToFlags()是上述函数OsCvtSecFlagsToAttrs的逆过程,用于把L1 Section类型页表项的MMU标签属性转换为内存区域映射标签属性。自行阅读代码,不再逐行分析。

⑴  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_SMPmmuFlags |= MMU_DESCRIPTOR_L1_SECTION_SHAREABLE;#endifbreak;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函数和OsCvtPte2AttsToFlags函数

和上一小节非常类似,上节是L1 Section类型页表项MMU属性和内存区域标签属性的相互转换,本节的2个函数是L2页表项MMU属性和内存区域标签属性的相互转换。函数OsCvtPte2FlagsToAttrs()把内存区域映射标签属性转换为L2页表项MMU属性,又分为2个函数,分别是⑴处的函数OsCvtPte2CacheFlagsToMMUFlags()和⑵处的OsCvtPte2AccessFlagsToMMUFlags()OsCvtPte2CacheFlagsToMMUFlags()函数主要判断内存映射区域的低2位缓存标签属性的转换。OsCvtPte2AccessFlagsToMMUFlags()函数用于映射标签属性的2-4位访问权限部分的转换。代码比较简单不再赘述。

⑶处的函数OsCvtPte2AttsToFlags()是上述函数OsCvtPte2FlagsToAttrs的逆过程,用于把L2页表项的MMU标签属性转换为内存区域映射标签属性。自行阅读代码,不再逐行分析。

⑴  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_SMPmmuFlags |= MMU_DESCRIPTOR_L2_SHAREABLE;#endifmmuFlags |= 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;}}

小结

本文介绍了MMU虚实映射的基本概念,运行机制,分析了映射初始化、映射查询、映射虚拟内存和物理内存,解除虚实映射,更改映射属性,重新映射等常用接口的代码。

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

在这里插入图片描述

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN/733GH/overview

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片
在这里插入图片描述


http://www.ppmy.cn/news/1525482.html

相关文章

Redis运维之监控指标,性能监控,监控方式,响应慢分析

文章目录 1 Redis监控1.1 Redis监控指标1.1.1 性能指标: Performance1.1.2 内存指标: Memory1.1.3 基本活动指标&#xff1a;Basic activity1.1.4 持久性指标: Persistence1.1.5 错误指标&#xff1a;Error 1.2 监控方式1.2.1 info1.2.2 性能监控1.2.3 内存监控1.2.4 基本活动指…

W外链怎么做微信推广链接?

"W外链"通常指的是一种可以创建短链接或者特殊功能的链接服务&#xff0c;这些链接可以用来在微信等社交平台上进行推广。由于微信对直接链接分享有一定的限制&#xff0c;使用这类服务可以帮助绕过这些限制&#xff0c;从而实现更有效的推广。 以下是使用W外链创建微…

解锁编程潜力,从掌握GitHub开始

目录&#xff1a; 一、搜索开源项目 1、什么是Git 2、Github常用词含义 3、一个完整的项目界面 4、使用Github搜索项目 1&#xff09;in关键词 2&#xff09;star或fork数量去查找 3&#xff09;awesome加强搜索 二、访问速度慢的解决 1、使用网易UU加速器 2、使用…

Linux:git

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《Linux&#xff1a;git》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#xff01;&…

应用层协议 —— https

目录 http的缺点 https 安全与加密 运营商挟持 常见的加密方式 对称加密 非对称加密 数据摘要&#xff08;数据指纹&#xff09; 不安全加密策略 1 只使用对称加密 2 只使用非对称加密 3 双方都是用非对称加密 4 对称加密和非对称加密 解决方案 CA证书 http的缺点 我们可…

二进制读写文件

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 这个文章主要是针对二进制文件的读写 大概会分为c语言对二进制文件读写和c对二进制文件的读写 查找资料看到这篇文章&#xff1a;二进制文件的读…

社群空间站9.9付费入群系统易支付版全套搭建教程

社群空间站9.9付费入群系统易支付版全套搭建教程 1.创建站点 2.搭建环境 php7.2 3.上传源码包 数据库批量修改sq9.dongge1.icu s10.dongge1.icu 改为你的域名 4.上传数据库 修改数据库文件/data/config/ 5.访问域名 6.账户密码 admin 123456 7.易支付修改…

Mastering openFrameworks_第十一章_网络

网络 网络为多个设备之间的数据交换提供了一种方式。它是一个主要组成部分,允许远程控制移动和平板设备应用程序中的一些参数,也用于使交互式项目在多台计算机上同步工作。在本章中,您将学习如何在openFrameworks项目中实现和使用OSC和TCP协议,具体如下: 网络基础 使用O…

【devops】devops-git之介绍以及日常使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

3.门锁_STM32_矩阵按键设备实现

概述 需求来源&#xff1a; 门锁肯定是要输入密码&#xff0c;这个门锁提供了两个输入密码的方式&#xff1a;一个是蓝牙输入&#xff0c;一个是按键输入。对于按键输入&#xff0c;采用矩阵按键来实现。矩阵按键是为了模拟触摸屏的按键输入&#xff0c;后续如果项目结束前还…

Android架构组件:MVVM模式的实战应用与数据绑定技巧

在Android开发中&#xff0c;MVVM&#xff08;Model-View-ViewModel&#xff09;架构模式已经成为一种流行的选择。MVVM模式将应用程序分为三个主要部分&#xff1a;Model&#xff08;数据层&#xff09;、View&#xff08;UI层&#xff09;和ViewModel&#xff08;连接数据和U…

Android MediaProjection录屏权限处理

MediaProjection服务在SystemServiceRegistry的静态块里面注册的 frameworks/base/core/java/android/app/SystemServiceRegistry.java public final class SystemServiceRegistry {private static final String TAG "SystemServiceRegistry";/** hide */public st…

软考攻略/超详细/系统集成项目管理工程师/基础知识分享10

4.3 应用架构&#xff08;掌握&#xff09; 应用架构的主要内容是规划出目标应用分层分域架构&#xff0c;根据业务架构规划目标应用域、应用组和目标应用组件 4.3.1 基本原则&#xff08;掌握&#xff09; &#xff08;1&#xff09;业务适配性原则&#xff1a;应用架构具备一…

停车位检测-停车场车位识别

YOLO Parking Spot 概述 停车场获取的图像训练了四个YOLO模型来检测车辆。目标是收集信息&#xff0c;并可能开发一种停车解决方案以改善交通流量并优化空间利用率。通过识别汽车&#xff0c;我们生成了一份报告&#xff0c;其中包含图像细节&#xff0c;如可用停车位的数量、…

VPP配置网卡多队列no bufs问题

在VPP配置文件/etc/vpp/startup.conf中启用网卡的多队列功能&#xff0c;指定接收和发送队列的数量。 dpdk { dev default { num-rx-queues 4 num-tx-queues 4 } 在测试中发现如下情况&#xff0c;网卡的rx no bufs错误计数非常高。 vpp # show hardware-interfaces GigabitEt…

51单片机-DS1302(实时时钟+可调时钟)(可参考主页上一节内容介绍)

作者&#xff1a;王开心 时间&#xff1a;2024.9.10 目的&#xff1a;手撕51 main.c #include <REGX52.H> #include "LCD1602.h" #include "DS1302.h" #include "Key.h" #include "Delay.h" #include "Timer0.h"u…

如何测量一个(传输网络)系统的容量

Little 定律就能反算系统容量&#xff0c;但我这篇文章要正着算。 假想一个理发店场景。李大爷拥有一家占地 50 平米的理发店&#xff0c;经理到店里理发如果已经有经理在理发&#xff0c;就要拿个券等待&#xff0c;请问李大爷需要印多少等待券&#xff1f; 这是个系统容量问…

Flutter自定义Icon的简易使用(两种)

方式一&#xff1a;利用第三方库&#xff08;建议&#xff09; 1、在阿里图标库(iconfont-阿里巴巴矢量图标库)上&#xff0c;加载购物车后&#xff0c;点击“下载素材”svg。 2、把下载的图片放入asstes目录下。​​​​​​​ 3、修改yaml配置文件&#xff0c;设置Icon图标所…

【自费2W真机测评】三款热门/旗舰宠物空气净化器米家、希喂、352对比试用!

我家老大是三个月大的时候接回来的&#xff0c;接回来前就是家教好的小猫咪一只&#xff0c;不乱尿、不掉毛的。看朋友家都被猫咪掉毛困扰着&#xff0c;我还嘚瑟觉得自己养可好了&#xff0c;根本不掉毛。养了三个月老大长成大猫猫了&#xff0c;我又觉得我可以了&#xff0c;…

【系统架构设计师】享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,它用于减少需要创建的对象数量,以节省内存。享元模式通过共享已经存在的对象来表示尽可能多的新对象,从而降低系统中对象的数量,提高性能。享元模式尤其适合于系统中存在大量相似对象的情况,通过共享公共的部分数据,可…