更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_vm_page.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "los_vm_page.h"
33#include "los_vm_common.h"
34#include "los_vm_phys.h"
35#include "los_vm_boot.h"
36#include "los_vm_filemap.h"
37
38
39#ifdef LOSCFG_KERNEL_VM
40
41LosVmPage *g_vmPageArray = NULL;//物理页框数组
42size_t g_vmPageArraySize;//物理页框大小
43//页框初始化
44STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
45{
46 LOS_ListInit(&page->node); //页节点初始化
47 page->flags = FILE_PAGE_FREE; //页标签,初始为空闲页
48 LOS_AtomicSet(&page->refCounts, 0); //引用次数0
49 page->physAddr = pa; //物理地址
50 page->segID = segID; //物理地址使用段管理,段ID
51 page->order = VM_LIST_ORDER_MAX; //初始化值,不属于任何块组
52 page->nPages = 0;
53#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
54 LOS_SpinInit(&page->lock);
55#endif
56}
57///伙伴算法初始化
58STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
59{//@note_why 此时所有页面 page->order = VM_LIST_ORDER_MAX,能挂入伙伴算法的链表吗?
60 OsVmPhysPagesFreeContiguous(page, nPages);//释放连续的物理页框
61}
62#define VMPAGEINIT(page, pa, segID) do { \
63 OsVmPageInit(page, pa, segID); \
64 (page)++; \
65 (pa) += PAGE_SIZE; \
66} while (0)
67
68/*!
69 完成对物理内存整体初始化,本函数一定运行在实模式下
70 1.申请大块内存g_vmPageArray存放LosVmPage,按4K一页划分物理内存存放在数组中.
71*/
73{
74 struct VmPhysSeg *seg = NULL;
75 LosVmPage *page = NULL;
76 paddr_t pa;
77 UINT32 nPage;
78 INT32 segID;
79
80 OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));//校正 g_physArea size
81
82 /*
83 * Pages getting from OsVmPhysPageNumGet() interface here contain the memory
84 * struct LosVmPage occupied, which satisfies the equation:
85 * nPage * sizeof(LosVmPage) + nPage * PAGE_SIZE = OsVmPhysPageNumGet() * PAGE_SIZE.
86 */
87 nPage = OsVmPhysPageNumGet() * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE);
88 g_vmPageArraySize = nPage * sizeof(LosVmPage);//页表总大小
89 g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);//实模式下申请内存,此时还没有初始化MMU
90
91 OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));//
92
93 OsVmPhysSegAdd();// 完成对段的初始化
94 OsVmPhysInit();// 加入空闲链表和设置置换算法,LRU(最近最久未使用)算法
95
96 for (segID = 0; segID < g_vmPhysSegNum; segID++) {//遍历物理段,将段切成一页一页
97 seg = &g_vmPhysSeg[segID];
98 nPage = seg->size >> PAGE_SHIFT;//本段总页数
99 UINT32 count = nPage >> 3; /* 3: 2 ^ 3, nPage / 8, cycle count */
100 UINT32 left = nPage & 0x7; /* 0x7: nPage % 8, left page */
101
102 for (page = seg->pageBase, pa = seg->start; count > 0; count--) {
103 /* note: process large amount of data, optimize performance */
104 VMPAGEINIT(page, pa, segID);
105 VMPAGEINIT(page, pa, segID);
106 VMPAGEINIT(page, pa, segID);
107 VMPAGEINIT(page, pa, segID);
108 VMPAGEINIT(page, pa, segID);
109 VMPAGEINIT(page, pa, segID);
110 VMPAGEINIT(page, pa, segID);
111 VMPAGEINIT(page, pa, segID);
112 }
113 for (; left > 0; left--) {
114 VMPAGEINIT(page, pa, segID);
115 }
116 OsVmPageOrderListInit(seg->pageBase, nPage);//伙伴算法初始化,将所有页加入空闲链表供分配
117 }
118}
119///通过物理地址获取页框
121{
122 INT32 segID;
123 LosVmPage *page = NULL;
124
125 for (segID = 0; segID < g_vmPhysSegNum; segID++) {//物理内存采用段页管理
126 page = OsVmPhysToPage(paddr, segID);//通过物理地址和段ID找出物理页框
127 if (page != NULL) {
128 break;
129 }
130 }
131
132 return page;
133}
134#endif
135
STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal)
Atomic setting.
Definition: los_atomic.h:147
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:37
unsigned long PADDR_T
Definition: los_typedef.h:207
signed int INT32
Definition: los_typedef.h:60
unsigned long paddr_t
Definition: los_typedef.h:209
unsigned char UINT8
Definition: los_typedef.h:55
unsigned int UINT32
Definition: los_typedef.h:57
VOID * OsVmBootMemAlloc(size_t len)
Definition: los_vm_boot.c:50
UINTPTR g_vmBootMemBase
虚拟内存区间检查, 需理解 los_vm_zone.h 中画出的鸿蒙虚拟内存全景图
Definition: los_vm_boot.c:45
@ FILE_PAGE_FREE
空闲页
LosVmPage * g_vmPageArray
物理页框(page frame)池,在g_vmPageArray中:不可能存在两个物理地址一样的物理页框,
Definition: los_vm_page.c:41
LosVmPage * LOS_VmPageGet(PADDR_T paddr)
通过物理地址获取页框
Definition: los_vm_page.c:120
STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
Definition: los_vm_page.c:44
STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
伙伴算法初始化
Definition: los_vm_page.c:58
VOID OsVmPageStartup(VOID)
Definition: los_vm_page.c:72
size_t g_vmPageArraySize
物理总页框(page frame)数
Definition: los_vm_page.c:42
struct VmPage LosVmPage
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
INT32 g_vmPhysSegNum
段总数
Definition: los_vm_phys.c:88
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
连续的释放物理页框, 如果8页连在一块是一起释放的
Definition: los_vm_phys.c:420
struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]
物理内存采用段页式管理,先切段后伙伴算法页
Definition: los_vm_phys.c:87
LosVmPage * OsVmPhysToPage(paddr_t pa, UINT8 segID)
通过物理地址获取所属参数段的物理页框
Definition: los_vm_phys.c:250
UINT32 OsVmPhysPageNumGet(VOID)
获得物理内存的总页数
Definition: los_vm_phys.c:152
VOID OsVmPhysSegAdd(VOID)
添加物理段
Definition: los_vm_phys.c:127
VOID OsVmPhysAreaSizeAdjust(size_t size)
段区域大小调整
Definition: los_vm_phys.c:141
VOID OsVmPhysInit(VOID)
物理段初始化
Definition: los_vm_phys.c:181
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
Definition: los_vm_page.h:53
SPIN_LOCK_S lock
Definition: los_vm_page.h:63
Atomic refCounts
Definition: los_vm_page.h:57
LOS_DL_LIST node
Definition: los_vm_page.h:54
UINT8 order
Definition: los_vm_page.h:59
UINT16 nPages
Definition: los_vm_page.h:61
UINT8 segID
Definition: los_vm_page.h:60
UINT32 flags
Definition: los_vm_page.h:58
PADDR_T physAddr
Definition: los_vm_page.h:56
物理段描述符
Definition: los_vm_phys.h:85
LosVmPage * pageBase
Definition: los_vm_phys.h:88
size_t size
Definition: los_vm_phys.h:87
PADDR_T start
Definition: los_vm_phys.h:86