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

铁佛  论坛元老 | 2024-9-11 15:26:50 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1029|帖子 1029|积分 3087

往期知识点记载:



  • 鸿蒙(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页表内存属性相干的宏,如下。

  1. /* TEX CB */
  2. #define MMU_DESCRIPTOR_L1_TEX_SHIFT                             12 /* type extension field shift */
  3. #define MMU_DESCRIPTOR_L1_TEX(x)                                \
  4.     ((x) << MMU_DESCRIPTOR_L1_TEX_SHIFT) /* type extension */
  5. #define MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED                 \
  6.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE)
  7. #define MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE                   \
  8.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE)
  9. #define MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED                    \
  10.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE)
  11. #define MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED                \
  12.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE)
  13. #define MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE       \
  14.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE)
  15. #define MMU_DESCRIPTOR_L1_TEX_TYPE_MASK                         \
  16.     (MMU_DESCRIPTOR_L1_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE)
  17. #define MMU_DESCRIPTOR_L1_AP2_SHIFT                             15
  18. #define MMU_DESCRIPTOR_L1_AP2(x)                                ((x) << MMU_DESCRIPTOR_L1_AP2_SHIFT)
  19. #define MMU_DESCRIPTOR_L1_AP2_0                                 (MMU_DESCRIPTOR_L1_AP2(0))
  20. #define MMU_DESCRIPTOR_L1_AP2_1                                 (MMU_DESCRIPTOR_L1_AP2(1))
  21. #define MMU_DESCRIPTOR_L1_AP01_SHIFT                            10
  22. #define MMU_DESCRIPTOR_L1_AP01(x)                               ((x) << MMU_DESCRIPTOR_L1_AP01_SHIFT)
  23. #define MMU_DESCRIPTOR_L1_AP01_0                                (MMU_DESCRIPTOR_L1_AP01(0))
  24. #define MMU_DESCRIPTOR_L1_AP01_1                                (MMU_DESCRIPTOR_L1_AP01(1))
  25. #define MMU_DESCRIPTOR_L1_AP01_3                                (MMU_DESCRIPTOR_L1_AP01(3))
  26. #define MMU_DESCRIPTOR_L1_AP_P_NA_U_NA                          (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_0)
  27. #define MMU_DESCRIPTOR_L1_AP_P_RW_U_RW                          (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_3)
  28. #define MMU_DESCRIPTOR_L1_AP_P_RW_U_NA                          (MMU_DESCRIPTOR_L1_AP2_0 | MMU_DESCRIPTOR_L1_AP01_1)
  29. #define MMU_DESCRIPTOR_L1_AP_P_RO_U_RO                          (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_3)
  30. #define MMU_DESCRIPTOR_L1_AP_P_RO_U_NA                          (MMU_DESCRIPTOR_L1_AP2_1 | MMU_DESCRIPTOR_L1_AP01_1)
  31. #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页表内存属性相干的宏,如下。

  1. #define MMU_DESCRIPTOR_L2_TEX_SHIFT                             6 /* type extension field shift */
  2. #define MMU_DESCRIPTOR_L2_TEX(x)                                \
  3.     ((x) << MMU_DESCRIPTOR_L2_TEX_SHIFT) /* type extension */
  4. #define MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED                 \
  5.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_NON_CACHEABLE)
  6. #define MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE                   \
  7.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_NON_CACHEABLE)
  8. #define MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED                    \
  9.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_0) | MMU_DESCRIPTOR_WRITE_BACK_ALLOCATE)
  10. #define MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED                \
  11.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_2) | MMU_DESCRIPTOR_NON_CACHEABLE)
  12. #define MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE       \
  13.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_1) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE)
  14. #define MMU_DESCRIPTOR_L2_TEX_TYPE_MASK                         \
  15.     (MMU_DESCRIPTOR_L2_TEX(MMU_DESCRIPTOR_TEX_MASK) | MMU_DESCRIPTOR_WRITE_BACK_NO_ALLOCATE)
  16. #define MMU_DESCRIPTOR_L2_AP2_SHIFT                             9
  17. #define MMU_DESCRIPTOR_L2_AP2(x)                                ((x) << MMU_DESCRIPTOR_L2_AP2_SHIFT)
  18. #define MMU_DESCRIPTOR_L2_AP2_0                                 (MMU_DESCRIPTOR_L2_AP2(0))
  19. #define MMU_DESCRIPTOR_L2_AP2_1                                 (MMU_DESCRIPTOR_L2_AP2(1))
  20. #define MMU_DESCRIPTOR_L2_AP01_SHIFT                            4
  21. #define MMU_DESCRIPTOR_L2_AP01(x)                               ((x) << MMU_DESCRIPTOR_L2_AP01_SHIFT)
  22. #define MMU_DESCRIPTOR_L2_AP01_0                                (MMU_DESCRIPTOR_L2_AP01(0))
  23. #define MMU_DESCRIPTOR_L2_AP01_1                                (MMU_DESCRIPTOR_L2_AP01(1))
  24. #define MMU_DESCRIPTOR_L2_AP01_3                                (MMU_DESCRIPTOR_L2_AP01(3))
  25. #define MMU_DESCRIPTOR_L2_AP_P_NA_U_NA                          (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_0)
  26. #define MMU_DESCRIPTOR_L2_AP_P_RW_U_RW                          (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_3)
  27. #define MMU_DESCRIPTOR_L2_AP_P_RW_U_NA                          (MMU_DESCRIPTOR_L2_AP2_0 | MMU_DESCRIPTOR_L2_AP01_1)
  28. #define MMU_DESCRIPTOR_L2_AP_P_RO_U_RO                          (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_3)
  29. #define MMU_DESCRIPTOR_L2_AP_P_RO_U_NA                          (MMU_DESCRIPTOR_L2_AP2_1 | MMU_DESCRIPTOR_L2_AP01_1)
  30. #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使用。

  1. /* the high 8 bits(24~31) should reserved, shm will use it */
  2. #define     VM_MAP_REGION_FLAG_CACHED               (0<<0)
  3. #define     VM_MAP_REGION_FLAG_UNCACHED             (1<<0)
  4. #define     VM_MAP_REGION_FLAG_UNCACHED_DEVICE      (2<<0) /* only exists on some arches, otherwise UNCACHED */
  5. #define     VM_MAP_REGION_FLAG_STRONGLY_ORDERED     (3<<0) /* only exists on some arches, otherwise UNCACHED */
  6. #define     VM_MAP_REGION_FLAG_CACHE_MASK           (3<<0)
  7. #define     VM_MAP_REGION_FLAG_PERM_USER            (1<<2)
  8. #define     VM_MAP_REGION_FLAG_PERM_READ            (1<<3)
  9. #define     VM_MAP_REGION_FLAG_PERM_WRITE           (1<<4)
  10. #define     VM_MAP_REGION_FLAG_PERM_EXECUTE         (1<<5)
  11. #define     VM_MAP_REGION_FLAG_PROT_MASK            (0xF<<2)
  12. #define     VM_MAP_REGION_FLAG_NS                   (1<<6) /* NON-SECURE */
  13. #define     VM_MAP_REGION_FLAG_SHARED               (1<<7)
  14. #define     VM_MAP_REGION_FLAG_PRIVATE              (1<<8)
  15. #define     VM_MAP_REGION_FLAG_FLAG_MASK            (3<<7)
  16. #define     VM_MAP_REGION_FLAG_STACK                (1<<9)
  17. #define     VM_MAP_REGION_FLAG_HEAP                 (1<<10)
  18. #define     VM_MAP_REGION_FLAG_DATA                 (1<<11)
  19. #define     VM_MAP_REGION_FLAG_TEXT                 (1<<12)
  20. #define     VM_MAP_REGION_FLAG_BSS                  (1<<13)
  21. #define     VM_MAP_REGION_FLAG_VDSO                 (1<<14)
  22. #define     VM_MAP_REGION_FLAG_MMAP                 (1<<15)
  23. #define     VM_MAP_REGION_FLAG_SHM                  (1<<16)
  24. #define     VM_MAP_REGION_FLAG_FIXED                (1<<17)
  25. #define     VM_MAP_REGION_FLAG_FIXED_NOREPLACE      (1<<18)
  26. #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_READ、MAP_SHARED等等,界说在文件third_party/musl/porting/liteos_a/kernel/include/sys/mman.h。
  1. STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
  2. {
  3.     UINT32 regionFlags = 0;
  4.     regionFlags |= VM_MAP_REGION_FLAG_PERM_USER;
  5.     regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0;
  6.     regionFlags |= (prot & PROT_WRITE) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0;
  7.     regionFlags |= (prot & PROT_EXEC) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE) : 0;
  8.     regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
  9.     regionFlags |= (flags & MAP_PRIVATE) ? VM_MAP_REGION_FLAG_PRIVATE : 0;
  10.     regionFlags |= (flags & MAP_FIXED) ? VM_MAP_REGION_FLAG_FIXED : 0;
  11.     regionFlags |= (flags & MAP_FIXED_NOREPLACE) ? VM_MAP_REGION_FLAG_FIXED_NOREPLACE : 0;
  12.     return regionFlags;
  13. }
复制代码
7.3.2 OsCvtSecFlagsToAttrs函数和OsCvtSecAttsToFlags函数

OsCvtSecFlagsToAttrs函数用于把内存区域映射标签属性转换为L1 Section范例页表项的MMU标签属性。该函数又分为2个函数,分别是⑴处的OsCvtSecCacheFlagsToMMUFlags()函数和⑵处的OsCvtSecAccessFlagsToMMUFlags()函数。OsCvtSecCacheFlagsToMMUFlags()函数主要判断内存映射区域的低2位缓存标签属性的转换。OsCvtSecAccessFlagsToMMUFlags()函数用于映射标签属性的2-4位访问权限部门的转换。代码比较简单不再赘述。
⑶处的函数OsCvtSecAttsToFlags()是上述函数OsCvtSecFlagsToAttrs的逆过程,用于把L1 Section范例页表项的MMU标签属性转换为内存区域映射标签属性。自行阅读代码,不再逐行分析。
  1. ⑴  STATIC UINT32 OsCvtSecCacheFlagsToMMUFlags(UINT32 flags)
  2.     {
  3.         UINT32 mmuFlags = 0;
  4.         switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) {
  5.             case VM_MAP_REGION_FLAG_CACHED:
  6.                 mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE;
  7.     #ifdef LOSCFG_KERNEL_SMP
  8.                 mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_SHAREABLE;
  9.     #endif
  10.                 break;
  11.             case VM_MAP_REGION_FLAG_STRONGLY_ORDERED:
  12.                 mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED;
  13.                 break;
  14.             case VM_MAP_REGION_FLAG_UNCACHED:
  15.                 mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE;
  16.                 break;
  17.             case VM_MAP_REGION_FLAG_UNCACHED_DEVICE:
  18.                 mmuFlags |= MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED;
  19.                 break;
  20.             default:
  21.                 return LOS_ERRNO_VM_INVALID_ARGS;
  22.         }
  23.         return mmuFlags;
  24.     }
  25. ⑵  STATIC UINT32 OsCvtSecAccessFlagsToMMUFlags(UINT32 flags)
  26.     {
  27.         UINT32 mmuFlags = 0;
  28.         switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) {
  29.             case 0:
  30.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA;
  31.                 break;
  32.             case VM_MAP_REGION_FLAG_PERM_READ:
  33.             case VM_MAP_REGION_FLAG_PERM_USER:
  34.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_NA;
  35.                 break;
  36.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ:
  37.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RO_U_RO;
  38.                 break;
  39.             case VM_MAP_REGION_FLAG_PERM_WRITE:
  40.             case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE:
  41.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_NA;
  42.                 break;
  43.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE:
  44.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE:
  45.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_RW_U_RW;
  46.                 break;
  47.             default:
  48.                 break;
  49.         }
  50.         return mmuFlags;
  51.     }
  52.     /* convert user level mmu flags to L1 descriptors flags */
  53.     STATIC UINT32 OsCvtSecFlagsToAttrs(UINT32 flags)
  54.     {
  55.         UINT32 mmuFlags;
  56.         mmuFlags = OsCvtSecCacheFlagsToMMUFlags(flags);
  57.         if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) {
  58.             return mmuFlags;
  59.         }
  60.         mmuFlags |= MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT;
  61.         mmuFlags |= OsCvtSecAccessFlagsToMMUFlags(flags);
  62.         if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) {
  63.             mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_XN;
  64.         }
  65.         if (flags & VM_MAP_REGION_FLAG_NS) {
  66.             mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_SECURE;
  67.         }
  68.         if (flags & VM_MAP_REGION_FLAG_PERM_USER) {
  69.             mmuFlags |= MMU_DESCRIPTOR_L1_SECTION_NON_GLOBAL;
  70.         }
  71.         return mmuFlags;
  72.     }
  73. ⑶  STATIC VOID OsCvtSecAttsToFlags(PTE_T l1Entry, UINT32 *flags)
  74.     {
  75.         *flags = 0;
  76.         if (l1Entry & MMU_DESCRIPTOR_L1_SECTION_NON_SECURE) {
  77.             *flags |= VM_MAP_REGION_FLAG_NS;
  78.         }
  79.         switch (l1Entry & MMU_DESCRIPTOR_L1_TEX_TYPE_MASK) {
  80.             case MMU_DESCRIPTOR_L1_TYPE_STRONGLY_ORDERED:
  81.                 *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED;
  82.                 break;
  83.             case MMU_DESCRIPTOR_L1_TYPE_NORMAL_NOCACHE:
  84.                 *flags |= VM_MAP_REGION_FLAG_UNCACHED;
  85.                 break;
  86.             case MMU_DESCRIPTOR_L1_TYPE_DEVICE_SHARED:
  87.             case MMU_DESCRIPTOR_L1_TYPE_DEVICE_NON_SHARED:
  88.                 *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE;
  89.                 break;
  90.             default:
  91.                 break;
  92.         }
  93.         *flags |= VM_MAP_REGION_FLAG_PERM_READ;
  94.         switch (l1Entry & MMU_DESCRIPTOR_L1_AP_MASK) {
  95.             case MMU_DESCRIPTOR_L1_AP_P_RO_U_NA:
  96.                 break;
  97.             case MMU_DESCRIPTOR_L1_AP_P_RW_U_NA:
  98.                 *flags |= VM_MAP_REGION_FLAG_PERM_WRITE;
  99.                 break;
  100.             case MMU_DESCRIPTOR_L1_AP_P_RO_U_RO:
  101.                 *flags |= VM_MAP_REGION_FLAG_PERM_USER;
  102.                 break;
  103.             case MMU_DESCRIPTOR_L1_AP_P_RW_U_RW:
  104.                 *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE;
  105.                 break;
  106.             default:
  107.                 break;
  108.         }
  109.         if (!(l1Entry & MMU_DESCRIPTOR_L1_SECTION_XN)) {
  110.             *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE;
  111.         }
  112.     }
复制代码
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标签属性转换为内存区域映射标签属性。自行阅读代码,不再逐行分析。
  1. ⑴  STATIC UINT32 OsCvtPte2CacheFlagsToMMUFlags(UINT32 flags)
  2.     {
  3.         UINT32 mmuFlags = 0;
  4.         switch (flags & VM_MAP_REGION_FLAG_CACHE_MASK) {
  5.             case VM_MAP_REGION_FLAG_CACHED:
  6.     #ifdef LOSCFG_KERNEL_SMP
  7.                 mmuFlags |= MMU_DESCRIPTOR_L2_SHAREABLE;
  8.     #endif
  9.                 mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_WRITE_BACK_ALLOCATE;
  10.                 break;
  11.             case VM_MAP_REGION_FLAG_STRONGLY_ORDERED:
  12.                 mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED;
  13.                 break;
  14.             case VM_MAP_REGION_FLAG_UNCACHED:
  15.                 mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE;
  16.                 break;
  17.             case VM_MAP_REGION_FLAG_UNCACHED_DEVICE:
  18.                 mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED;
  19.                 break;
  20.             default:
  21.                 return LOS_ERRNO_VM_INVALID_ARGS;
  22.         }
  23.         return mmuFlags;
  24.     }
  25. ⑵  STATIC UINT32 OsCvtPte2AccessFlagsToMMUFlags(UINT32 flags)
  26.     {
  27.         UINT32 mmuFlags = 0;
  28.         switch (flags & (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE)) {
  29.             case 0:
  30.                 mmuFlags |= MMU_DESCRIPTOR_L1_AP_P_NA_U_NA;
  31.                 break;
  32.             case VM_MAP_REGION_FLAG_PERM_READ:
  33.             case VM_MAP_REGION_FLAG_PERM_USER:
  34.                 mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_NA;
  35.                 break;
  36.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ:
  37.                 mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RO_U_RO;
  38.                 break;
  39.             case VM_MAP_REGION_FLAG_PERM_WRITE:
  40.             case VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE:
  41.                 mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_NA;
  42.                 break;
  43.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE:
  44.             case VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE:
  45.                 mmuFlags |= MMU_DESCRIPTOR_L2_AP_P_RW_U_RW;
  46.                 break;
  47.             default:
  48.                 break;
  49.         }
  50.         return mmuFlags;
  51.     }
  52.     /* convert user level mmu flags to L2 descriptors flags */
  53.     STATIC UINT32 OsCvtPte2FlagsToAttrs(UINT32 flags)
  54.     {
  55.         UINT32 mmuFlags;
  56.         mmuFlags = OsCvtPte2CacheFlagsToMMUFlags(flags);
  57.         if (mmuFlags == LOS_ERRNO_VM_INVALID_ARGS) {
  58.             return mmuFlags;
  59.         }
  60.         mmuFlags |= OsCvtPte2AccessFlagsToMMUFlags(flags);
  61.         if (!(flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) {
  62.             mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN;
  63.         } else {
  64.             mmuFlags |= MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE;
  65.         }
  66.         if (flags & VM_MAP_REGION_FLAG_PERM_USER) {
  67.             mmuFlags |= MMU_DESCRIPTOR_L2_NON_GLOBAL;
  68.         }
  69.         return mmuFlags;
  70.     }
  71. ⑶  STATIC VOID OsCvtPte2AttsToFlags(PTE_T l1Entry, PTE_T l2Entry, UINT32 *flags)
  72.     {
  73.         *flags = 0;
  74.         /* NS flag is only present on L1 entry */
  75.         if (l1Entry & MMU_DESCRIPTOR_L1_PAGETABLE_NON_SECURE) {
  76.             *flags |= VM_MAP_REGION_FLAG_NS;
  77.         }
  78.         switch (l2Entry & MMU_DESCRIPTOR_L2_TEX_TYPE_MASK) {
  79.             case MMU_DESCRIPTOR_L2_TYPE_STRONGLY_ORDERED:
  80.                 *flags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED;
  81.                 break;
  82.             case MMU_DESCRIPTOR_L2_TYPE_NORMAL_NOCACHE:
  83.                 *flags |= VM_MAP_REGION_FLAG_UNCACHED;
  84.                 break;
  85.             case MMU_DESCRIPTOR_L2_TYPE_DEVICE_SHARED:
  86.             case MMU_DESCRIPTOR_L2_TYPE_DEVICE_NON_SHARED:
  87.                 *flags |= VM_MAP_REGION_FLAG_UNCACHED_DEVICE;
  88.                 break;
  89.             default:
  90.                 break;
  91.         }
  92.         *flags |= VM_MAP_REGION_FLAG_PERM_READ;
  93.         switch (l2Entry & MMU_DESCRIPTOR_L2_AP_MASK) {
  94.             case MMU_DESCRIPTOR_L2_AP_P_RO_U_NA:
  95.                 break;
  96.             case MMU_DESCRIPTOR_L2_AP_P_RW_U_NA:
  97.                 *flags |= VM_MAP_REGION_FLAG_PERM_WRITE;
  98.                 break;
  99.             case MMU_DESCRIPTOR_L2_AP_P_RO_U_RO:
  100.                 *flags |= VM_MAP_REGION_FLAG_PERM_USER;
  101.                 break;
  102.             case MMU_DESCRIPTOR_L2_AP_P_RW_U_RW:
  103.                 *flags |= VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_WRITE;
  104.                 break;
  105.             default:
  106.                 break;
  107.         }
  108.         if ((l2Entry & MMU_DESCRIPTOR_L2_TYPE_MASK) != MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN) {
  109.             *flags |= VM_MAP_REGION_FLAG_PERM_EXECUTE;
  110.         }
  111.     }
复制代码
小结

本文介绍了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




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

铁佛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表