/* Physical memory area array */
STATIC struct VmPhysArea g_physArea[] = {
{
.start = SYS_MEM_BASE, //整个物理内存基地址
.size = SYS_MEM_SIZE_DEFAULT,//整个物理内存总大小
},
};
//* page初始化
VOID OsVmPageStartup(VOID)
{
struct VmPhysSeg *seg = NULL;
LosVmPage *page = NULL;
paddr_t pa;
UINT32 nPage;
INT32 segID;
OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));//校正 g_physArea size
nPage = OsVmPhysPageNumGet();//得到 g_physArea 总页数
g_vmPageArraySize = nPage * sizeof(LosVmPage);//页表总大小
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);//申请页表存放区域
OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));// g_physArea 变小
OsVmPhysSegAdd();// 段页绑定
OsVmPhysInit();// 加入空闲链表和设置置换算法,LRU(最近最久未使用)算法
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
seg = &g_vmPhysSeg[segID];
nPage = seg->size >> PAGE_SHIFT;
for (page = seg->pageBase, pa = seg->start; page <= seg->pageBase + nPage;
page++, pa += PAGE_SIZE) {
OsVmPageInit(page, pa, segID);//page初始化
}
OsVmPageOrderListInit(seg->pageBase, nPage);// 页面分配的排序
}
}
UINT32 OsVmPhysPageNumGet(VOID)
{
UINT32 nPages = 0;
INT32 i;
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
nPages += g_physArea[i].size >> PAGE_SHIFT;//右移12位,相当于除以4K,得出总页数
}
return nPages;
}
VOID OsVmPhysSegAdd(VOID)
{
INT32 i, ret;
LOS_ASSERT(g_vmPhysSegNum <= VM_PHYS_SEG_MAX);
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);//一个区对应一个段
if (ret != 0) {
VM_ERR("create phys seg failed");
}
}
}
STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
{
LOS_ListInit(&page->node);//初始化链表节点
page->flags = FILE_PAGE_FREE;//默认空闲
LOS_AtomicSet(&page->refCounts, 0);//0次引用
page->physAddr = pa;//物理地址
page->segID = segID;//所属段
page->order = VM_LIST_ORDER_MAX;//伙伴算法默认级数
}