48#ifdef LOSCFG_KERNEL_VM
52 if ((len == 0) || (len > USER_ASPACE_SIZE)) {
59 if (((flags & MAP_FIXED) == 0) && ((flags & MAP_FIXED_NOREPLACE) == 0)) {
60 *vaddr = ROUNDUP(*vaddr, PAGE_SIZE);
68 if ((flags & MAP_SUPPORT_MASK) == 0) {
71 if (((flags & MAP_SHARED_PRIVATE) == 0) || ((flags & MAP_SHARED_PRIVATE) == MAP_SHARED_PRIVATE)) {
75 if (((len >> PAGE_SHIFT) + pgoff) < pgoff) {
84 if (!((
unsigned int)filep->
f_oflags & O_RDWR) && (((
unsigned int)filep->
f_oflags & O_ACCMODE) ^ O_RDONLY)) {
87 if (flags & MAP_SHARED) {
88 if (((
unsigned int)filep->
f_oflags & O_APPEND) && (prot & PROT_WRITE)) {
91 if ((prot & PROT_WRITE) && !((
unsigned int)filep->
f_oflags & O_RDWR)) {
155 struct file *filep = NULL;
158 len = ROUNDUP(len, PAGE_SIZE);
160 if (checkRst != LOS_OK) {
165 status = fs_getfilep(fd, &filep);
179 if (status == LOS_OK) {
186 if (newRegion == NULL) {
187 resultVaddr = (
VADDR_T)-ENOMEM;
199 if (status != LOS_OK) {
202 resultVaddr = (
VADDR_T)-ENOMEM;
213 if ((addr <= 0) || (size <= 0)) {
224 permFlags |= ((fileFlags & O_ACCMODE) ^ O_RDONLY) ? 0 : VM_MAP_REGION_FLAG_PERM_READ;
225 permFlags |= (fileFlags & O_WRONLY) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0;
226 permFlags |= (fileFlags & O_RDWR) ? (VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE) : 0;
227 protFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0;
228 protFlags |= (prot & PROT_WRITE) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0;
230 return ((protFlags & permFlags) == protFlags);
239 if (
LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) {
265 VOID *alignAddr = NULL;
266 VOID *shrinkAddr = NULL;
273 return (VOID *)-ENOMEM;
277 size = ROUNDUP(size, PAGE_SIZE);
279 PRINT_INFO(
"brk addr %p , size 0x%x, alignAddr %p, align %d\n", addr, size, alignAddr, PAGE_SIZE);
289 VM_ERR(
"Process heap memory space is insufficient");
290 ret = (VOID *)-ENOMEM;
291 goto REGION_ALLOC_FAILED;
296 VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |
297 VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_USER, 0);
298 if (region == NULL) {
299 ret = (VOID *)-ENOMEM;
300 VM_ERR(
"LOS_RegionAlloc failed");
301 goto REGION_ALLOC_FAILED;
304 space->
heap = region;
320 if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) {
321 vmFlags |= VM_MAP_REGION_FLAG_HEAP;
322 }
else if (oldRegionFlags & VM_MAP_REGION_FLAG_STACK) {
323 vmFlags |= VM_MAP_REGION_FLAG_STACK;
324 }
else if (oldRegionFlags & VM_MAP_REGION_FLAG_TEXT) {
325 vmFlags |= VM_MAP_REGION_FLAG_TEXT;
326 }
else if (oldRegionFlags & VM_MAP_REGION_FLAG_VDSO) {
327 vmFlags |= VM_MAP_REGION_FLAG_VDSO;
328 }
else if (oldRegionFlags & VM_MAP_REGION_FLAG_MMAP) {
329 vmFlags |= VM_MAP_REGION_FLAG_MMAP;
330 }
else if (oldRegionFlags & VM_MAP_REGION_FLAG_SHM) {
331 vmFlags |= VM_MAP_REGION_FLAG_SHM;
347 if (!IS_ALIGNED(vaddr, PAGE_SIZE) || (region == NULL) || (vaddr > vaddr + len)) {
352 if ((prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))) {
381 vmFlags |= (region->
regionFlags & VM_MAP_REGION_FLAG_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
384 if (region == NULL) {
389 count = len >> PAGE_SHIFT;
398#ifdef LOSCFG_VM_OVERLAP_CHECK
399 if (VmmAspaceRegionsOverlapCheck(aspace) < 0) {
415 if ((region == NULL) || (region->
range.
base > addr) || (newLen == 0)) {
419 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) {
423 if (((flags & MREMAP_FIXED) == MREMAP_FIXED) && ((flags & MREMAP_MAYMOVE) == 0)) {
427 if (!IS_ALIGNED(addr, PAGE_SIZE)) {
434 if (oldLen > regionEnd - addr) {
439 if (newLen > oldLen) {
440 if ((addr + newLen) < addr) {
446 if (flags & MREMAP_FIXED) {
448 (region->
range.
base < (newAddr + newLen))) {
452 if (!IS_ALIGNED(newAddr, PAGE_SIZE)) {
473 status =
OsMremapCheck(oldAddress, oldSize, newAddr, newSize, (
unsigned int)flags);
487 if (regionOld == NULL) {
492 if ((
unsigned int)flags & MREMAP_FIXED) {
493 regionNew =
OsVmRegionDup(space, regionOld, newAddr, newSize);
499 ((newSize < regionOld->range.size) ? newSize : regionOld->
range.
size) >> PAGE_SHIFT,
511 if (oldSize > newSize) {
512 LOS_UnMMap(oldAddress + newSize, oldSize - newSize);
524 if ((
unsigned int)flags & MREMAP_MAYMOVE) {
526 if (regionNew == NULL) {
544#ifdef LOSCFG_VM_OVERLAP_CHECK
545 if (VmmAspaceRegionsOverlapCheck(aspace) < 0) {
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
Align the value (addr) by some bytes (boundary) you specify.
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 将进程空间一个虚拟地址区间的映射关系转移至另一块未使用的虚拟地址区间重新做映射。
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
VOID LOS_RbDelNode(LosRbTree *pstTree, LosRbNode *pstNode)
VOID OsDumpAspace(LosVmSpace *space)
dump 指定虚拟空间的信息
VOID OsDumpPte(VADDR_T vaddr)
dump 页表项
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m)
STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m)
INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len)
STATIC INLINE BOOL LOS_IsRegionTypeFile(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)
STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion *region)
设为匿名swap映射线性区
LosVmMapRegion * OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size)
STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size)
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
从外部权限标签转化为线性区权限标签
LosVmMapRegion * LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr)
查找线性区 根据起始地址在进程空间内查找是否存在
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)
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size)
STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T vaddr, size_t size)
STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newLen, unsigned int flags)
STATUS_T LOS_UnMMap(VADDR_T addr, size_t size)
解除映射关系
STATUS_T OsAnonMMap(LosVmMapRegion *region)
匿名映射
STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags)
继承老线性区的标签
STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *region)
VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff)
VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr)
重新映射虚拟内存地址。
VOID * LOS_DoBrk(VOID *addr)
VOID LOS_DumpMemRegion(VADDR_T vaddr)
输出内存线性区
VOID * OsShrinkHeap(VOID *addr, LosVmSpace *space)
收缩堆区
STATUS_T OsNamedMmapingPermCheck(struct file *filep, unsigned long flags, unsigned prot)
STATUS_T OsCheckMMapParams(VADDR_T *vaddr, unsigned long flags, size_t len, unsigned long pgoff)
INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
修改内存段的访问权限
STATIC INLINE BOOL LOS_IsNamedMapping(unsigned long flags)
struct VmMapRegion::@4::VmRegionFile rf
union VmMapRegion::@4 unTypeData
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[])
查看进程的虚拟内存使用情况。vmm [-a / -h / –help], vmm [pid]