虚实映射其实就是一个建立页表的过程 http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.html 更多...
结构体 | |
struct | MmuMapInfo |
函数 | |
__attribute__ ((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS))) | |
STATIC SPIN_LOCK_S * | OsGetPte1Lock (LosArchMmu *archMmu, PADDR_T paddr, UINT32 *intSave) |
STATIC INLINE VOID | OsUnlockPte1 (SPIN_LOCK_S *lock, UINT32 intSave) |
STATIC SPIN_LOCK_S * | OsGetPte1LockTmp (LosArchMmu *archMmu, PADDR_T paddr, UINT32 *intSave) |
STATIC INLINE VOID | OsUnlockPte1Tmp (SPIN_LOCK_S *lock, UINT32 intSave) |
STATIC INLINE SPIN_LOCK_S * | OsGetPte2Lock (LosArchMmu *archMmu, PTE_T pte1, UINT32 *intSave) |
STATIC INLINE VOID | OsUnlockPte2 (SPIN_LOCK_S *lock, UINT32 intSave) |
STATIC INLINE PTE_T * | OsGetPte2BasePtr (PTE_T pte1) |
获取页表基地址 更多... | |
VADDR_T * | OsGFirstTableGet (VOID) |
STATIC INLINE UINT32 | OsUnmapL1Invalid (vaddr_t *vaddr, UINT32 *count) |
解除L1表的映射关系 更多... | |
STATIC INT32 | OsMapParamCheck (UINT32 flags, VADDR_T vaddr, PADDR_T paddr) |
STATIC VOID | OsCvtPte2AttsToFlags (PTE_T l1Entry, PTE_T l2Entry, UINT32 *flags) |
STATIC VOID | OsPutL2Table (const LosArchMmu *archMmu, UINT32 l1Index, paddr_t l2Paddr) |
STATIC VOID | OsTryUnmapL1PTE (LosArchMmu *archMmu, PTE_T *l1Entry, vaddr_t vaddr, UINT32 scanIndex, UINT32 scanCount) |
STATIC UINT32 | OsCvtSecCacheFlagsToMMUFlags (UINT32 flags) |
STATIC UINT32 | OsCvtSecAccessFlagsToMMUFlags (UINT32 flags) |
STATIC UINT32 | OsCvtSecFlagsToAttrs (UINT32 flags) |
STATIC VOID | OsCvtSecAttsToFlags (PTE_T l1Entry, UINT32 *flags) |
STATIC UINT32 | OsUnmapL2PTE (LosArchMmu *archMmu, PTE_T *pte1, vaddr_t vaddr, UINT32 *count) |
STATIC UINT32 | OsUnmapSection (LosArchMmu *archMmu, PTE_T *l1Entry, vaddr_t *vaddr, UINT32 *count) |
BOOL | OsArchMmuInit (LosArchMmu *archMmu, VADDR_T *virtTtb) |
STATUS_T | LOS_ArchMmuQuery (const LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T *paddr, UINT32 *flags) |
LOS_ArchMmuQuery 获取进程空间虚拟地址对应的物理地址以及映射属性。 本函数是内核高频函数,通过MMU查询虚拟地址是否映射过,带走映射的物理地址和权限 更多... | |
STATUS_T | LOS_ArchMmuUnmap (LosArchMmu *archMmu, VADDR_T vaddr, size_t count) |
LOS_ArchMmuUnmap 解除进程空间虚拟地址区间与物理地址区间的映射关系 更多... | |
STATIC UINT32 | OsMapSection (MmuMapInfo *mmuMapInfo, UINT32 *count) |
OsMapSection section页表格式项映射 更多... | |
STATIC STATUS_T | OsGetL2Table (LosArchMmu *archMmu, UINT32 l1Index, paddr_t *ppa) |
获取L2页表,分配L2表(需物理内存) 更多... | |
STATIC UINT32 | OsCvtPte2CacheFlagsToMMUFlags (UINT32 flags) |
STATIC UINT32 | OsCvtPte2AccessFlagsToMMUFlags (UINT32 flags) |
STATIC UINT32 | OsCvtPte2FlagsToAttrs (UINT32 flags) |
STATIC UINT32 | OsMapL1PTE (MmuMapInfo *mmuMapInfo, PTE_T *l1Entry, UINT32 *count) |
STATIC UINT32 | OsMapL2PageContinous (MmuMapInfo *mmuMapInfo, PTE_T *pte1, UINT32 *count) |
status_t | LOS_ArchMmuMap (LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T paddr, size_t count, UINT32 flags) |
LOS_ArchMmuMap 映射进程空间虚拟地址区间与物理地址区间 所谓的map就是生成L1,L2页表项的过程 更多... | |
STATUS_T | LOS_ArchMmuChangeProt (LosArchMmu *archMmu, VADDR_T vaddr, size_t count, UINT32 flags) |
LOS_ArchMmuChangeProt 修改进程空间虚拟地址区间的映射属性 改变内存段的访问权限,例如: 读/写/可执行/不可用 == 更多... | |
STATUS_T | LOS_ArchMmuMove (LosArchMmu *archMmu, VADDR_T oldVaddr, VADDR_T newVaddr, size_t count, UINT32 flags) |
LOS_ArchMmuMove 将进程空间一个虚拟地址区间的映射关系转移至另一块未使用的虚拟地址区间重新做映射。 更多... | |
VOID | LOS_ArchMmuContextSwitch (LosArchMmu *archMmu) |
LOS_ArchMmuContextSwitch 切换MMU上下文 更多... | |
STATUS_T | LOS_ArchMmuDestroy (LosArchMmu *archMmu) |
LOS_ArchMmuDestroy 销毁MMU 和 initMmu 相呼应,释放页表页 更多... | |
STATIC VOID | OsSwitchTmpTTB (VOID) |
切换临时页表 更多... | |
STATIC VOID | OsSetKSectionAttr (UINTPTR virtAddr, BOOL uncached) |
设置内核空间段属性,可看出内核空间是固定映射到物理地址 更多... | |
STATIC VOID | OsKSectionNewAttrEnable (VOID) |
VOID | OsArchMmuInitPerCPU (VOID) |
VOID | OsInitMappingStartUp (VOID) |
OsInitMappingStartUp 开始初始化mmu 更多... | |
虚实映射其实就是一个建立页表的过程 http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.html
虚实映射是指系统通过内存管理单元(MMU,Memory Management Unit)将进程空间的虚拟地址与实际的物理地址做映射, 并指定相应的访问权限、缓存属性等。程序执行时,CPU访问的是虚拟内存,通过MMU页表条目找到对应的物理内存, 并做相应的代码执行或数据读写操作。MMU的映射由页表(Page Table)来描述,其中保存虚拟地址和物理地址的映射关系以及访问权限等。 每个进程在创建的时候都会创建一个页表,页表由一个个页表条目(Page Table Entry, PTE)构成, 每个页表条目描述虚拟地址区间与物理地址区间的映射关系。MMU中有一块页表缓存,称为快表(TLB, Translation Lookaside Buffers), 做地址转换时,MMU首先在TLB中查找,如果找到对应的页表条目可直接进行转换,提高了查询效率。 虚实映射其实就是一个建立页表的过程。MMU有多级页表,LiteOS-A内核采用二级页表描述进程空间。每个一级页表条目描述符占用4个字节, 可表示1MiB的内存空间的映射关系,即1GiB用户空间(LiteOS-A内核中用户空间占用1GiB)的虚拟内存空间需要1024个。系统创建用户进程时, 在内存中申请一块4KiB大小的内存块作为一级页表的存储区域,二级页表根据当前进程的需要做动态的内存申请。 用户程序加载启动时,会将代码段、数据段映射进虚拟内存空间(详细可参考动态加载与链接),此时并没有物理页做实际的映射; 程序执行时,如下图粗箭头所示,CPU访问虚拟地址,通过MMU查找是否有对应的物理内存,若该虚拟地址无对应的物理地址则触发缺页异常, 内核申请物理内存并将虚实映射关系及对应的属性配置信息写进页表,并把页表条目缓存至TLB,接着CPU可直接通过转换关系访问实际的物理内存; 若CPU访问已缓存至TLB的页表条目,无需再访问保存在内存中的页表,可加快查找速度。 开发流程 1. 虚实映射相关接口的使用: 通过LOS_ArchMmuMap映射一块物理内存。 2. 对映射的地址区间做相关操作: 通过LOS_ArchMmuQuery可以查询相应虚拟地址区间映射的物理地址区间及映射属性; 通过LOS_ArchMmuChangeProt修改映射属性; 通过LOS_ArchMmuMove做虚拟地址区间的重映射。 3. 通过LOS_ArchMmuUnmap解除映射关系。 *
@history
在文件 los_arch_mmu.c 中定义.
__attribute__ | ( | (aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)) | ) |
在文件 los_arch_mmu.c 第 98 行定义.
STATUS_T LOS_ArchMmuChangeProt | ( | LosArchMmu * | archMmu, |
VADDR_T | vaddr, | ||
size_t | count, | ||
UINT32 | flags | ||
) |
LOS_ArchMmuChangeProt 修改进程空间虚拟地址区间的映射属性 改变内存段的访问权限,例如: 读/写/可执行/不可用 ==
archMmu | |
count | |
flags | |
vaddr |
在文件 los_arch_mmu.c 第 949 行定义.
VOID LOS_ArchMmuContextSwitch | ( | LosArchMmu * | archMmu | ) |
LOS_ArchMmuContextSwitch 切换MMU上下文
archMmu |
在文件 los_arch_mmu.c 第 1044 行定义.
STATUS_T LOS_ArchMmuDestroy | ( | LosArchMmu * | archMmu | ) |
LOS_ArchMmuDestroy 销毁MMU 和 initMmu 相呼应,释放页表页
archMmu |
在文件 los_arch_mmu.c 第 1083 行定义.
status_t LOS_ArchMmuMap | ( | LosArchMmu * | archMmu, |
VADDR_T | vaddr, | ||
PADDR_T | paddr, | ||
size_t | count, | ||
UINT32 | flags | ||
) |
LOS_ArchMmuMap 映射进程空间虚拟地址区间与物理地址区间
所谓的map就是生成L1,L2页表项的过程
archMmu | |
count | |
flags | |
paddr | |
vaddr |
在文件 los_arch_mmu.c 第 891 行定义.
STATUS_T LOS_ArchMmuMove | ( | LosArchMmu * | archMmu, |
VADDR_T | oldVaddr, | ||
VADDR_T | newVaddr, | ||
size_t | count, | ||
UINT32 | flags | ||
) |
LOS_ArchMmuMove 将进程空间一个虚拟地址区间的映射关系转移至另一块未使用的虚拟地址区间重新做映射。
archMmu | |
count | |
flags | |
newVaddr | |
oldVaddr |
在文件 los_arch_mmu.c 第 996 行定义.
STATUS_T LOS_ArchMmuQuery | ( | const LosArchMmu * | archMmu, |
VADDR_T | vaddr, | ||
PADDR_T * | paddr, | ||
UINT32 * | flags | ||
) |
LOS_ArchMmuQuery 获取进程空间虚拟地址对应的物理地址以及映射属性。
本函数是内核高频函数,通过MMU查询虚拟地址是否映射过,带走映射的物理地址和权限
archMmu | |
flags | |
paddr | |
vaddr |
在文件 los_arch_mmu.c 第 569 行定义.
STATUS_T LOS_ArchMmuUnmap | ( | LosArchMmu * | archMmu, |
VADDR_T | vaddr, | ||
size_t | count | ||
) |
LOS_ArchMmuUnmap 解除进程空间虚拟地址区间与物理地址区间的映射关系
archMmu | |
count | |
vaddr |
在文件 los_arch_mmu.c 第 619 行定义.
BOOL OsArchMmuInit | ( | LosArchMmu * | archMmu, |
VADDR_T * | virtTtb | ||
) |
在文件 los_arch_mmu.c 第 537 行定义.
VOID OsArchMmuInitPerCPU | ( | VOID | ) |
在文件 los_arch_mmu.c 第 752 行定义.
在文件 los_arch_mmu.c 第 782 行定义.
在文件 los_arch_mmu.c 第 379 行定义.
在文件 los_arch_mmu.c 第 409 行定义.
STATIC STATUS_T OsGetL2Table | ( | LosArchMmu * | archMmu, |
UINT32 | l1Index, | ||
paddr_t * | ppa | ||
) |
获取L2页表,分配L2表(需物理内存)
在文件 los_arch_mmu.c 第 686 行定义.
STATIC SPIN_LOCK_S * OsGetPte1Lock | ( | LosArchMmu * | archMmu, |
PADDR_T | paddr, | ||
UINT32 * | intSave | ||
) |
STATIC SPIN_LOCK_S * OsGetPte1LockTmp | ( | LosArchMmu * | archMmu, |
PADDR_T | paddr, | ||
UINT32 * | intSave | ||
) |
获取页表基地址
在文件 los_arch_mmu.c 第 180 行定义.
STATIC INLINE SPIN_LOCK_S * OsGetPte2Lock | ( | LosArchMmu * | archMmu, |
PTE_T | pte1, | ||
UINT32 * | intSave | ||
) |
VADDR_T * OsGFirstTableGet | ( | VOID | ) |
VOID OsInitMappingStartUp | ( | VOID | ) |
OsInitMappingStartUp 开始初始化mmu
在文件 los_arch_mmu.c 第 1263 行定义.
STATIC VOID OsKSectionNewAttrEnable | ( | VOID | ) |
在文件 los_arch_mmu.c 第 1222 行定义.
STATIC UINT32 OsMapL1PTE | ( | MmuMapInfo * | mmuMapInfo, |
PTE_T * | l1Entry, | ||
UINT32 * | count | ||
) |
在文件 los_arch_mmu.c 第 806 行定义.
STATIC UINT32 OsMapL2PageContinous | ( | MmuMapInfo * | mmuMapInfo, |
PTE_T * | pte1, | ||
UINT32 * | count | ||
) |
在文件 los_arch_mmu.c 第 851 行定义.
STATIC UINT32 OsMapSection | ( | MmuMapInfo * | mmuMapInfo, |
UINT32 * | count | ||
) |
OsMapSection section页表格式项映射
archMmu | |
count | |
flags | |
paddr | |
vaddr |
在文件 los_arch_mmu.c 第 666 行定义.
STATIC VOID OsPutL2Table | ( | const LosArchMmu * | archMmu, |
UINT32 | l1Index, | ||
paddr_t | l2Paddr | ||
) |
在文件 los_arch_mmu.c 第 266 行定义.
设置内核空间段属性,可看出内核空间是固定映射到物理地址
在文件 los_arch_mmu.c 第 1127 行定义.
STATIC VOID OsSwitchTmpTTB | ( | VOID | ) |
切换临时页表
在文件 los_arch_mmu.c 第 1098 行定义.
STATIC VOID OsTryUnmapL1PTE | ( | LosArchMmu * | archMmu, |
PTE_T * | l1Entry, | ||
vaddr_t | vaddr, | ||
UINT32 | scanIndex, | ||
UINT32 | scanCount | ||
) |
在文件 los_arch_mmu.c 第 292 行定义.
STATIC INLINE VOID OsUnlockPte1 | ( | SPIN_LOCK_S * | lock, |
UINT32 | intSave | ||
) |
在文件 los_arch_mmu.c 第 135 行定义.
STATIC INLINE VOID OsUnlockPte1Tmp | ( | SPIN_LOCK_S * | lock, |
UINT32 | intSave | ||
) |
STATIC INLINE VOID OsUnlockPte2 | ( | SPIN_LOCK_S * | lock, |
UINT32 | intSave | ||
) |
STATIC UINT32 OsUnmapL2PTE | ( | LosArchMmu * | archMmu, |
PTE_T * | pte1, | ||
vaddr_t | vaddr, | ||
UINT32 * | count | ||
) |
在文件 los_arch_mmu.c 第 482 行定义.
STATIC UINT32 OsUnmapSection | ( | LosArchMmu * | archMmu, |
PTE_T * | l1Entry, | ||
vaddr_t * | vaddr, | ||
UINT32 * | count | ||
) |