37#ifndef __LOS_VM_MAP_H__
38#define __LOS_VM_MAP_H__
55file结构体来自 ..\third_party\NuttX\include\nuttx\fs\fs.h
81#define KMALLOC_LARGE_SIZE (PAGE_SIZE << 2)
130 struct VmRegionFile {
136 struct VmRegionAnon {
158#ifdef LOSCFG_DRIVERS_TZDRIVER
164#define VM_MAP_REGION_TYPE_NONE (0x0)
165#define VM_MAP_REGION_TYPE_ANON (0x1)
166#define VM_MAP_REGION_TYPE_FILE (0x2)
167#define VM_MAP_REGION_TYPE_DEV (0x4)
168#define VM_MAP_REGION_TYPE_MASK (0x7)
171#define VM_MAP_REGION_FLAG_CACHED (0<<0)
172#define VM_MAP_REGION_FLAG_UNCACHED (1<<0)
173#define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0)
174#define VM_MAP_REGION_FLAG_STRONGLY_ORDERED (3<<0)
175#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0)
176#define VM_MAP_REGION_FLAG_PERM_USER (1<<2)
177#define VM_MAP_REGION_FLAG_PERM_READ (1<<3)
178#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4)
179#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5)
180#define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2)
181#define VM_MAP_REGION_FLAG_NS (1<<6)
182#define VM_MAP_REGION_FLAG_SHARED (1<<7)
183#define VM_MAP_REGION_FLAG_PRIVATE (1<<8)
184#define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7)
185#define VM_MAP_REGION_FLAG_STACK (1<<9)
186#define VM_MAP_REGION_FLAG_HEAP (1<<10)
187#define VM_MAP_REGION_FLAG_DATA (1<<11)
188#define VM_MAP_REGION_FLAG_TEXT (1<<12)
189#define VM_MAP_REGION_FLAG_BSS (1<<13)
190#define VM_MAP_REGION_FLAG_VDSO (1<<14)
191#define VM_MAP_REGION_FLAG_MMAP (1<<15)
192#define VM_MAP_REGION_FLAG_SHM (1<<16)
193#define VM_MAP_REGION_FLAG_FIXED (1<<17)
194#define VM_MAP_REGION_FLAG_FIXED_NOREPLACE (1<<18)
195#define VM_MAP_REGION_FLAG_INVALID (1<<19)
201 regionFlags |= VM_MAP_REGION_FLAG_PERM_USER;
202 regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0;
203 regionFlags |= (prot & PROT_WRITE) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0;
204 regionFlags |= (prot & PROT_EXEC) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE) : 0;
205 regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
206 regionFlags |= (flags & MAP_PRIVATE) ? VM_MAP_REGION_FLAG_PRIVATE : 0;
207 regionFlags |= (flags & MAP_FIXED) ? VM_MAP_REGION_FLAG_FIXED : 0;
208 regionFlags |= (flags & MAP_FIXED_NOREPLACE) ? VM_MAP_REGION_FLAG_FIXED_NOREPLACE : 0;
215 return ((vaddr >= (
VADDR_T)KERNEL_ASPACE_BASE) &&
216 (vaddr <= ((
VADDR_T)KERNEL_ASPACE_BASE + ((
VADDR_T)KERNEL_ASPACE_SIZE - 1))));
231 return (end - start + 1);
236 return region->
regionType == VM_MAP_REGION_TYPE_FILE;
241 return ((region->
regionFlags & VM_MAP_REGION_FLAG_PROT_MASK) ==
242 (VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ));
247 return ((region->
regionFlags & VM_MAP_REGION_FLAG_FLAG_MASK) == VM_MAP_REGION_FLAG_PRIVATE);
257 return region->
regionType == VM_MAP_REGION_TYPE_DEV;
267 return region->
regionType == VM_MAP_REGION_TYPE_ANON;
277 return ((vaddr >= USER_ASPACE_BASE) &&
278 (vaddr <= (USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1))));
289 return ((vaddr >= VMALLOC_START) &&
290 (vaddr <= (VMALLOC_START + (VMALLOC_SIZE - 1))));
https://blog.csdn.net/qq_38410730/article/details/81036768
unsigned long VM_OFFSET_T
VOID LOS_VFree(const VOID *addr)
STATIC INLINE BOOL OsIsVmRegionEmpty(LosVmSpace *vmSpace)
是否为一个空线性区
STATIC INLINE BOOL LOS_IsKernelAddress(VADDR_T vaddr)
虚拟地址是否在内核空间
STATIC INLINE size_t LOS_RegionSize(VADDR_T start, VADDR_T end)
获取线性区大小
INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len)
STATIC INLINE BOOL LOS_IsKernelAddressRange(VADDR_T vaddr, size_t len)
给定地址范围是否都在内核空间中
LosVmSpace * LOS_CurrSpaceGet(VOID)
获取当前进程空间结构体指针
STATIC INLINE BOOL LOS_IsRegionTypeDev(LosVmMapRegion *region)
是否为设备映射线性区 /dev/...
STATIC INLINE VOID LOS_SetRegionTypeFile(LosVmMapRegion *region)
设置线性区为文件映射
PADDR_T LOS_PaddrQuery(VOID *vaddr)
通过虚拟地址查询映射的物理地址
STATIC INLINE BOOL LOS_IsVmallocAddress(VADDR_T vaddr)
STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
STATIC INLINE BOOL LOS_IsRegionTypeFile(LosVmMapRegion *region)
是否为文件映射区
LosMux * OsGVmSpaceMuxGet(VOID)
struct VmFault LosVmPgFault
缺页结构信息体
STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T vaddr, size_t size)
BOOL LOS_IsRegionFileValid(LosVmMapRegion *region)
映射类型为文件的线性区是否有效
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
虚拟地址[vaddr,vaddr + len]是否在用户空间
BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size)
LosVmSpace * LOS_SpaceGet(VADDR_T vaddr)
获取虚拟地址对应的进程空间结构体指针
STATIC INLINE BOOL LOS_IsRegionPermUserReadOnly(LosVmMapRegion *region)
permanent 用户进程永久/常驻区
LosVmSpace * OsCreateUserVmSpace(VOID)
创建用户进程空间
struct VmMapRange LosVmMapRange
LosVmSpace * LOS_GetVmallocSpace(VOID)
获取内核堆空间的全局变量
STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion *region)
设为匿名swap映射线性区
STATIC INLINE VADDR_T LOS_RegionEndAddr(LosVmMapRegion *region)
获取线性区的结束地址
STATIC INLINE VOID LOS_SetRegionTypeDev(LosVmMapRegion *region)
设为设备映射线性区
STATIC INLINE BOOL LOS_IsRegionTypeAnon(LosVmMapRegion *region)
是否为匿名swap映射线性区
VOID * LOS_KernelMalloc(UINT32 size)
struct VmSpace LosVmSpace
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
LOS_DL_LIST * LOS_GetVmSpaceList(VOID)
获取进程空间链表指针 g_vmSpaceList中挂的是进程空间 g_kVmSpace, g_vMallocSpace,所有用户进程的空间(独有一个进程空间)
LosVmMapRegion * OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size)
STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size)
LosVmMapRegion * OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset)
创建一个线性区
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
从外部权限标签转化为线性区权限标签
LosVmMapRegion * LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr)
查找线性区 根据起始地址在进程空间内查找是否存在
VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len)
分配指定长度的线性区
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace)
LosVmSpace * LOS_GetKVmSpace(VOID)
内核空间只有g_kVmSpace一个,所有的内核进程都共用一个内核空间
STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags)
STATIC INLINE BOOL LOS_IsRegionFlagPrivateOnly(LosVmMapRegion *region)
是否为私有线性区
VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags)
分配指定开始地址和长度的线性区
STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region)
释放进程空间指定线性区
LosVmMapRegion * LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff)
BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb)
OsUserVmSpaceInit 用户空间的TTB表是动态申请得来,每个进程有属于自己的L1,L2表 初始化用户进程虚拟空间,主要划分数据区,堆区,映射区和创建mmu
VOID * LOS_KernelRealloc(VOID *ptr, UINT32 size)
VOID OsInitMappingStartUp(VOID)
OsInitMappingStartUp 开始初始化mmu
STATUS_T OsVmSpaceRegionFree(LosVmSpace *space)
BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region)
向红黑树中插入线性区
VOID LOS_KernelFree(VOID *ptr)
VOID * LOS_VMalloc(size_t size)
LosVmMapRegion * LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len)
查找线性区 根据地址区间在进程空间内查找是否存在
VOID OsKSpaceInit(VOID)
内核虚拟空间初始化
STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr)
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size)
STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T vaddr, size_t size)
VOID * LOS_KernelMallocAlign(UINT32 size, UINT32 boundary)
内存管理单元(英语:memory management unit,缩写为MMU),有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。
虚拟内存文件操作函数指针,上层开发可理解为 class 里的方法,注意是对线性区的操作 , 文件操作 见于g_commVmOps
int(* fault)(struct VmMapRegion *region, LosVmPgFault *pageFault)
缺页,OsVmmFileFault
void(* open)(struct VmMapRegion *region)
打开
void(* close)(struct VmMapRegion *region)
关闭
void(* remove)(struct VmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T offset)
删除 OsVmmFileRemove
struct VmMapRegion::@4::VmRegionFile rf
union VmMapRegion::@4 unTypeData
const LosVmFileOps * vmFOps
文件处理各操作接口,open,read,write,close,mmap
LosVmSpace * space
所属虚拟空间,虚拟空间由多个线性区组成
struct VmMapRegion::@4::VmRegionDev rd
struct VmMapRegion::@4::VmRegionAnon ra
struct Vnode * vnode
文件索引节点
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
struct page_mapping * f_mapping
FAR struct inode * f_inode
unsigned long flags
@note_why 全量代码中也没查到源码中对其操作
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void