100#ifdef LOSCFG_KERNEL_VM
102#define VM_MAP_WASTE_MEM_LEVEL (PAGE_SIZE >> 2)
137 return &g_vmSpaceList;
158 return (VOID *)®ion->
range;
172 }
else if (startA >= startB) {
178 }
else if (startA <= startB) {
184 }
else if (endA < startB) {
204 if (retval != LOS_OK) {
205 VM_ERR(
"Create mutex for vm space failed, status: %d", retval);
219 if (retval != LOS_OK) {
220 VM_ERR(
"Create mutex for g_vmSpaceList failed, status: %d", retval);
226 vmSpace->
base = KERNEL_ASPACE_BASE;
227 vmSpace->
size = KERNEL_ASPACE_SIZE;
228 vmSpace->
mapBase = KERNEL_VMM_BASE;
229 vmSpace->
mapSize = KERNEL_VMM_SIZE;
230#ifdef LOSCFG_DRIVERS_TZDRIVER
239 vmSpace->
base = VMALLOC_START;
240 vmSpace->
size = VMALLOC_SIZE;
241 vmSpace->
mapBase = VMALLOC_START;
242 vmSpace->
mapSize = VMALLOC_SIZE;
243#ifdef LOSCFG_DRIVERS_TZDRIVER
267 vmSpace->
base = USER_ASPACE_BASE;
268 vmSpace->
size = USER_ASPACE_SIZE;
269 vmSpace->
mapBase = USER_MAP_BASE;
270 vmSpace->
mapSize = USER_MAP_SIZE;
272 vmSpace->
heapNow = USER_HEAP_BASE;
273 vmSpace->
heap = NULL;
274#ifdef LOSCFG_DRIVERS_TZDRIVER
296 (VOID)memset_s(ttb, PAGE_SIZE, 0, PAGE_SIZE);
299 if ((retVal == FALSE) || (vmPage == NULL)) {
311 if (vmSpace == NULL) {
334 return LOS_ERRNO_VM_INVALID_ARGS;
338 return LOS_ERRNO_VM_INVALID_ARGS;
346 RB_SCAN_SAFE(&oldVmSpace->
regionRbTree, pstRbNode, pstRbNodeNext)
349 if (newRegion == NULL) {
350 VM_ERR(
"dup new region failed");
351 ret = LOS_ERRNO_VM_NO_MEMORY;
355#ifdef LOSCFG_KERNEL_SHM
356 if (oldRegion->
regionFlags & VM_MAP_REGION_FLAG_SHM) {
357 OsShmFork(newVmSpace, oldRegion, newRegion);
362 if (oldRegion == oldVmSpace->
heap) {
363 newVmSpace->
heap = newRegion;
366 numPages = newRegion->
range.
size >> PAGE_SHIFT;
367 for (i = 0; i < numPages; i++) {
368 vaddr = newRegion->
range.
base + (i << PAGE_SHIFT);
377 if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) {
388 if ((fpage != NULL) && (fpage->
vmPage == page)) {
395 RB_SCAN_SAFE_END(&oldVmSpace->
regionRbTree, pstRbNode, pstRbNodeNext)
405 rangeKey.
base = vaddr;
408 if (
LOS_RbGetNode(regionRbTree, (VOID *)&rangeKey, &pstRbNode)) {
446 if (curRegion != NULL) {
447 pstRbNode = &curRegion->
rbNode;
449 RB_MID_SCAN(regionRbTree, pstRbNode)
452 if (nextStart < curEnd) {
455 if ((nextStart - curEnd) >= len) {
460 RB_MID_SCAN_END(regionRbTree, pstRbNode)
463 RB_SCAN_SAFE(regionRbTree, pstRbNode, pstRbNodeTmp)
466 if (nextStart < curEnd) {
469 if ((nextStart - curEnd) >= len) {
474 RB_SCAN_SAFE_END(regionRbTree, pstRbNode, pstRbNodeTmp)
478 if ((nextStart >= curEnd) && ((nextStart - curEnd) >= len)) {
496 if ((regionFlags & VM_MAP_REGION_FLAG_FIXED_NOREPLACE) != 0) {
498 }
else if ((regionFlags & VM_MAP_REGION_FLAG_FIXED) != 0) {
500 if (status != LOS_OK) {
501 VM_ERR(
"unmap specific range va: %#x, len: %#x failed, status: %d", vaddr, len, status);
524 VM_ERR(
"insert region failed, base: %#x, size: %#x", region->
range.
base, region->
range.
size);
534 if (region == NULL) {
535 VM_ERR(
"memory allocate for LosVmMapRegion failed");
542 region->
pgOff = offset;
565 VM_ERR(
"vaddr is beyond range");
570 if (status == LOS_OK) {
585 BOOL isInsertSucceed = FALSE;
598 VM_ERR(
"alloc specific range va: %#x, len: %#x failed", vaddr, len);
607 if (newRegion == NULL) {
610 newRegion->
space = vmSpace;
612 if (isInsertSucceed == FALSE) {
631 if ((archMmu == NULL) || (vaddr == 0) || (count == 0)) {
632 VM_ERR(
"OsAnonPagesRemove invalid args, archMmu %p, vaddr %p, count %d", archMmu, vaddr, count);
639 if (status != LOS_OK) {
660 if ((archMmu == NULL) || (vaddr == 0) || (count == 0)) {
661 VM_ERR(
"OsDevPagesRemove invalid args, archMmu %p, vaddr %p, count %d", archMmu, vaddr, count);
666 if (status != LOS_OK) {
680 if ((space == NULL) || (region == NULL) || (region->
unTypeData.
rf.vmFOps == NULL)) {
684 offset = region->
pgOff;
686 while (size >= PAGE_SIZE) {
696 if ((space == NULL) || (region == NULL)) {
697 VM_ERR(
"args error, aspace %p, region %p", space, region);
698 return LOS_ERRNO_VM_INVALID_ARGS;
711#ifdef LOSCFG_KERNEL_SHM
739 regionFlags &= ~(VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_FIXED_NOREPLACE);
741 regionFlags |= VM_MAP_REGION_FLAG_FIXED;
744 if (newRegion == NULL) {
745 VM_ERR(
"LOS_RegionAlloc failed");
750#ifdef LOSCFG_KERNEL_SHM
784 if (newRegion == NULL) {
785 VM_ERR(
"OsVmRegionDup fail");
789 newRegion->
pgOff = oldRegion->
pgOff + ((newRegionStart - oldRegion->
range.
base) >> PAGE_SHIFT);
797 VADDR_T nextRegionBase = newRegionStart + size;
801 if ((region != NULL) && (newRegionStart > region->
range.
base)) {
802 newRegion = OsVmRegionSplit(region, newRegionStart);
803 if (newRegion == NULL) {
804 VM_ERR(
"region split fail");
805 return LOS_ERRNO_VM_NO_MEMORY;
811 newRegion = OsVmRegionSplit(region, nextRegionBase);
812 if (newRegion == NULL) {
813 VM_ERR(
"region split fail");
814 return LOS_ERRNO_VM_NO_MEMORY;
824 VADDR_T regionEnd = regionBase + size - 1;
832 if (status != LOS_OK) {
833 goto ERR_REGION_SPLIT;
836 RB_SCAN_SAFE(&space->
regionRbTree, pstRbNodeTemp, pstRbNodeNext)
838 if (regionTemp->
range.
base > regionEnd) {
841 if (regionBase <= regionTemp->range.base && regionEnd >=
LOS_RegionEndAddr(regionTemp)) {
843 if (status != LOS_OK) {
844 VM_ERR(
"fail to free region, status=%d", status);
845 goto ERR_REGION_SPLIT;
849 RB_SCAN_SAFE_END(&space->
regionRbTree, pstRbNodeTemp, pstRbNodeNext)
869 if (vmRegion == NULL) {
873 if (vmRegion == vmSpace->
heap) {
879 VM_ERR(
"unmap failed, ret = %d", ret);
897 if ((space == NULL) || (region == NULL)) {
903 if ((nextRegion != NULL) && ((nextRegion->
range.
base - region->
range.
base) >= size)) {
916 if (status != LOS_OK) {
918 VM_ERR(
"region_split failed");
919 goto ERR_REGION_SPLIT;
927STATIC VOID OsVmSpaceAllRegionFree(
LosVmSpace *space)
933 RB_SCAN_SAFE(&space->
regionRbTree, pstRbNode, pstRbNodeNext)
936 VM_ERR(
"space free, region: %#x flags: %#x, base:%#x, size: %#x",
941 VM_ERR(
"free region error, space %p, region %p", space, region);
943 RB_SCAN_SAFE_END(&space->
regionRbTree, pstRbNode, pstRbNodeNext)
951 return LOS_ERRNO_VM_INVALID_ARGS;
955 VM_ERR(
"try to free kernel aspace, not allowed");
960 OsVmSpaceAllRegionFree(space);
969 return LOS_ERRNO_VM_INVALID_ARGS;
973 VM_ERR(
"try to free kernel aspace, not allowed");
981 OsVmSpaceAllRegionFree(space);
985 if (currentProcess->
vmSpace == space) {
987 currentProcess->
vmSpace = NULL;
1006 if (vaddr < space->base || vaddr > space->
base + space->
size - 1) {
1013 if (vaddr + size - 1 < vaddr) {
1017 if (vaddr + size - 1 > space->
base + space->
size - 1) {
1027 if ((space == NULL) || (size == 0) || (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(size))) {
1028 return LOS_ERRNO_VM_INVALID_ARGS;
1032 return LOS_ERRNO_VM_OUT_OF_RANGE;
1041 return region ? LOS_OK : LOS_ERRNO_VM_NO_MEMORY;
1050 if ((vaddr != ROUNDUP(vaddr, PAGE_SIZE)) ||
1051 (paddr != ROUNDUP(paddr, PAGE_SIZE)) ||
1052 (len != ROUNDUP(len, PAGE_SIZE))) {
1053 VM_ERR(
"vaddr :0x%x paddr:0x%x len: 0x%x not page size align", vaddr, paddr, len);
1054 return LOS_ERRNO_VM_NOT_VALID;
1057 if (space == NULL) {
1062 if (region != NULL) {
1063 VM_ERR(
"vaddr : 0x%x already used!", vaddr);
1064 return LOS_ERRNO_VM_BUSY;
1068 if (region == NULL) {
1070 return LOS_ERRNO_VM_NO_MEMORY;
1075 if (vmPage == NULL) {
1077 VM_ERR(
"Page is NULL");
1078 return LOS_ERRNO_VM_NOT_VALID;
1084 VM_ERR(
"LOS_ArchMmuMap failed: %d", ret);
1109 if ((size == 0) || (size > space->
size)) {
1112 sizeCount = size >> PAGE_SHIFT;
1118 if (count < sizeCount) {
1119 VM_ERR(
"failed to allocate enough pages (ask %zu, got %zu)", sizeCount, count);
1124 region =
LOS_RegionAlloc(space, 0, size, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE, 0);
1125 if (region == NULL) {
1126 VM_ERR(
"alloc region failed, size = %x", size);
1131 while ((vmPage = LOS_ListRemoveHeadType(&pageList,
LosVmPage, node))) {
1136 VM_ERR(
"LOS_ArchMmuMap failed!, err;%d", ret);
1157 VM_ERR(
"addr is NULL!");
1164 if (region == NULL) {
1165 VM_ERR(
"find region failed");
1171 VM_ERR(
"free region failed, ret = %d", ret);
1182STATIC INLINE
BOOL OsMemLargeAlloc(
UINT32 size)
1188 if (size < KMALLOC_LARGE_SIZE) {
1209#ifdef LOSCFG_KERNEL_VM
1210 if (OsMemLargeAlloc(size)) {
1225#ifdef LOSCFG_KERNEL_VM
1226 if (OsMemLargeAlloc(size) && IS_ALIGNED(PAGE_SIZE, boundary)) {
1239 VOID *tmpPtr = NULL;
1241#ifdef LOSCFG_KERNEL_VM
1251 VM_ERR(
"page of ptr(%#x) is null", ptr);
1255 if (tmpPtr == NULL) {
1256 VM_ERR(
"alloc memory failed");
1259 ret = memcpy_s(tmpPtr, size, ptr, page->
nPages << PAGE_SHIFT);
1262 VM_ERR(
"KernelRealloc memcpy error");
1279#ifdef LOSCFG_KERNEL_VM
1283 if (ret != LOS_OK) {
1284 VM_ERR(
"KernelFree %p failed", ptr);
STATIC INLINE VOID LOS_AtomicInc(Atomic *v)
Atomic addSelf.
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
Align the value (addr) by some bytes (boundary) you specify.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a new node to a doubly linked list.
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
VOID * LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size)
按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块
VOID * LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
销毁互斥锁
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
Unlock the task scheduling.
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
Lock the task scheduling.
https://blog.csdn.net/qq_38410730/article/details/81036768
VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu)
LOS_ArchMmuContextSwitch 切换MMU上下文
STATUS_T LOS_ArchMmuDestroy(LosArchMmu *archMmu)
LOS_ArchMmuDestroy 销毁MMU 和 initMmu 相呼应,释放页表页
STATUS_T LOS_ArchMmuMap(LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T paddr, size_t count, UINT32 flags)
LOS_ArchMmuMap 映射进程空间虚拟地址区间与物理地址区间 所谓的map就是生成L1,L2页表项的过程
VADDR_T * OsGFirstTableGet(VOID)
BOOL OsArchMmuInit(LosArchMmu *archMmu, VADDR_T *virtTtb)
STATUS_T LOS_ArchMmuUnmap(LosArchMmu *archMmu, VADDR_T vaddr, size_t count)
LOS_ArchMmuUnmap 解除进程空间虚拟地址区间与物理地址区间的映射关系
STATUS_T LOS_ArchMmuQuery(const LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T *paddr, UINT32 *flags)
LOS_ArchMmuQuery 获取进程空间虚拟地址对应的物理地址以及映射属性。 本函数是内核高频函数,通过MMU查询虚拟地址是否映射过,带走映射的物理地址和权限
BOOL OsMemIsHeapNode(const VOID *ptr)
UINT32 OsMemLargeNodeFree(const VOID *ptr)
大内存释放
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
ULONG_T LOS_RbAddNode(LosRbTree *pstTree, LosRbNode *pstNew)
VOID LOS_RbInitTree(LosRbTree *pstTree, pfRBCmpKeyFn pfCmpKey, pfRBFreeFn pfFree, pfRBGetKeyFn pfGetKey)
VOID LOS_RbDelNode(LosRbTree *pstTree, LosRbNode *pstNode)
VOID * LOS_RbSuccessorNode(LosRbTree *pstTree, VOID *pstData)
ULONG_T LOS_RbGetNode(LosRbTree *pstTree, VOID *pKey, LosRbNode **ppstNode)
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
unsigned long VM_OFFSET_T
BOOL g_kHeapInited
内核堆区初始化变量
VOID OsDumpAspace(LosVmSpace *space)
dump 指定虚拟空间的信息
VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
是否为共享页
LosFilePage * OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m)
STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m)
STATIC BOOL OsVmSpaceInitCommon(LosVmSpace *vmSpace, VADDR_T *virtTtb)
OsVmSpaceInitCommon 初始化进程虚拟空间,必须提供L1表的虚拟内存地址
LosVmSpace * LOS_CurrSpaceGet(VOID)
获取当前进程空间结构体指针
LosMux g_vmSpaceListMux
用于锁g_vmSpaceList的互斥量
ULONG_T OsRegionRbCmpKeyFn(const VOID *pNodeKeyA, const VOID *pNodeKeyB)
比较两个红黑树节点
STATIC VOID OsAnonPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count)
PADDR_T LOS_PaddrQuery(VOID *vaddr)
通过虚拟地址查询映射的物理地址
STATIC BOOL OsVmSpaceParamCheck(LosVmSpace *vmSpace)
ULONG_T OsRegionRbFreeFn(LosRbNode *pstNode)
释放挂在红黑树上节点,等于释放了线性区
LOS_DL_LIST_HEAD(g_vmSpaceList)
初始化全局虚拟空间节点,所有虚拟空间都挂到此节点上.
BOOL LOS_IsRegionFileValid(LosVmMapRegion *region)
映射类型为文件的线性区是否有效
LosVmSpace * LOS_SpaceGet(VADDR_T vaddr)
获取虚拟地址对应的进程空间结构体指针
LosVmSpace * OsCreateUserVmSpace(VOID)
创建用户进程空间
STATIC VOID OsFilePagesRemove(LosVmSpace *space, LosVmMapRegion *region)
LosVmSpace * LOS_GetVmallocSpace(VOID)
获取内核堆空间的全局变量
BOOL OsKernVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb)
初始化内核虚拟空间
LOS_DL_LIST * LOS_GetVmSpaceList(VOID)
获取进程空间链表指针 g_vmSpaceList中挂的是进程空间 g_kVmSpace, g_vMallocSpace,所有用户进程的空间(独有一个进程空间)
LosVmMapRegion * OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset)
创建一个线性区
STATIC VOID OsDevPagesRemove(LosArchMmu *archMmu, VADDR_T vaddr, UINT32 count)
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一个,所有的内核进程都共用一个内核空间
BOOL OsVMallocSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb)
初始化内核堆空间
VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags)
分配指定开始地址和长度的线性区
STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region)
释放进程空间指定线性区
VOID OsVmMapInit(VOID)
@note_thinking 这个函数名称和内容不太搭
LosVmSpace g_vMallocSpace
内核分配空间,用于内核分配内存
VOID * OsRegionRbGetKeyFn(LosRbNode *pstNode)
通过红黑树节点找到对应的线性区
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
BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region)
向红黑树中插入线性区
LosVmMapRegion * LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len)
查找线性区 根据地址区间在进程空间内查找是否存在
LosVmSpace g_kVmSpace
内核非分配空间,用于内核运行栈,代码区,数据区
VOID OsKSpaceInit(VOID)
内核虚拟空间初始化
LosVmMapRegion * OsFindRegion(LosRbTree *regionRbTree, VADDR_T vaddr, size_t len)
通过虚拟(线性)地址查找所属线性区,红黑树
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_IsRegionTypeDev(LosVmMapRegion *region)
是否为设备映射线性区 /dev/...
STATIC INLINE BOOL LOS_IsVmallocAddress(VADDR_T vaddr)
STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
STATIC INLINE BOOL LOS_IsRegionTypeFile(LosVmMapRegion *region)
是否为文件映射区
LosMux * OsGVmSpaceMuxGet(VOID)
STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T vaddr, size_t size)
BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size)
STATIC INLINE VADDR_T LOS_RegionEndAddr(LosVmMapRegion *region)
获取线性区的结束地址
VOID * LOS_KernelMalloc(UINT32 size)
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
LosVmMapRegion * OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size)
STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size)
STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags)
struct VmMapRegion LosVmMapRegion
VOID * LOS_KernelRealloc(VOID *ptr, UINT32 size)
STATUS_T OsVmSpaceRegionFree(LosVmSpace *space)
VOID LOS_KernelFree(VOID *ptr)
VOID * LOS_VMalloc(size_t size)
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)
LosVmPage * LOS_VmPageGet(PADDR_T paddr)
通过物理地址获取页框
VOID * LOS_PhysPagesAllocContiguous(size_t nPages)
分配连续的物理页
VOID LOS_PhysPageFree(LosVmPage *page)
释放一个物理页框
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
释放指定页数地址连续的物理内存
size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list)
LOS_PhysPagesAlloc 分配nPages页个物理页框,并将页框挂入list 返回已分配的页面大小,不负责一定能分配到nPages的页框
size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
释放双链表中的所有节点内存,本质是回归到伙伴orderlist中
LosVmPage * OsVmVaddrToPage(VOID *ptr)
通过虚拟地址找映射的物理页框
VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion)
fork 一个共享线性区
BOOL OsIsShmRegion(LosVmMapRegion *region)
是否为共享线性区,是否有标签?
VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region)
释放共享线性区
STATUS_T LOS_UnMMap(VADDR_T addr, size_t size)
解除映射关系
内存管理单元(英语:memory management unit,缩写为MMU),有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。
struct VmPage * vmPage
物理页框
struct VmMapRegion::@4::VmRegionFile rf
union VmMapRegion::@4 unTypeData
LosVmSpace * space
所属虚拟空间,虚拟空间由多个线性区组成
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
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
int VnodeHold(void)
拿锁,封装互斥量