5-malloc.md (#25)
[lunaix-os.git] / lunaix-os / includes / lunaix / mm / vmm.h
1 #ifndef __LUNAIX_VMM_H
2 #define __LUNAIX_VMM_H
3 #include <lunaix/mm/page.h>
4 #include <lunaix/process.h>
5 #include <lunaix/types.h>
6 // Virtual memory manager
7
8 #define VMAP_NULL 0
9
10 /**
11  * @brief 映射模式:忽略已存在映射
12  *
13  */
14 #define VMAP_IGNORE 1
15
16 /**
17  * @brief 映射模式:不作实际映射。该功能用于预留出特定的地址空间
18  *
19  */
20 #define VMAP_NOMAP 2
21
22 /**
23  * @brief 映射页墙:将虚拟地址映射为页墙,忽略给定的物理地址和页属性
24  *
25  */
26 #define VMAP_GUARDPAGE 4
27
28 /**
29  * @brief 规定下一个可用页映射应当限定在指定的4MB地址空间内
30  *
31  */
32 #define VALLOC_PDE 1
33
34 /**
35  * @brief 初始化虚拟内存管理器
36  *
37  */
38 void
39 vmm_init();
40
41 /**
42  * @brief 创建一个页目录
43  *
44  * @return ptd_entry* 页目录的物理地址,随时可以加载进CR3
45  */
46 x86_page_table*
47 vmm_init_pd();
48
49 /**
50  * @brief 在指定地址空间中,添加一个映射
51  *
52  * @param mnt 地址空间挂载点
53  * @param va 虚拟地址
54  * @param pa 物理地址
55  * @param attr 映射属性
56  * @return int
57  */
58 int
59 vmm_set_mapping(ptr_t mnt, ptr_t va, ptr_t pa, pt_attr attr, int options);
60
61 /**
62  * @brief 删除一个映射
63  *
64  * @param mnt
65  * @param pid
66  * @param va
67  * @return int
68  */
69 ptr_t
70 vmm_del_mapping(ptr_t mnt, ptr_t va);
71
72 /**
73  * @brief 在当前虚拟地址空间里查找一个映射
74  *
75  * @param va 虚拟地址
76  * @param mapping 映射相关属性
77  */
78 int
79 vmm_lookup(ptr_t va, v_mapping* mapping);
80
81 /**
82  * @brief 在指定的虚拟地址空间里查找一个映射
83  *
84  * @param mnt 地址空间锚定点
85  * @param va 虚拟地址
86  * @param mapping 映射相关属性
87  * @return int
88  */
89 int
90 vmm_lookupat(ptr_t mnt, ptr_t va, v_mapping* mapping);
91
92 /**
93  * @brief (COW) 为虚拟页创建副本。
94  *
95  * @return void* 包含虚拟页副本的物理页地址。
96  *
97  */
98 ptr_t
99 vmm_dup_page(ptr_t pa);
100
101 /**
102  * @brief 挂载另一个虚拟地址空间至当前虚拟地址空间
103  *
104  * @param pde 页目录的物理地址
105  * @return ptr_t
106  */
107 ptr_t
108 vmm_mount_pd(ptr_t mnt, ptr_t pde);
109
110 /**
111  * @brief 卸载已挂载的虚拟地址空间
112  *
113  */
114 ptr_t
115 vmm_unmount_pd(ptr_t mnt);
116
117 static inline ptr_t 
118 vmm_mount_pg(ptr_t mnt, ptr_t pa) {
119     assert(pa);
120     vmm_set_mapping(VMS_SELF, mnt, pa, PG_PREM_RW, 0);
121     return mnt;
122 }
123
124 static inline ptr_t 
125 vmm_unmount_pg(ptr_t mnt) {
126     vmm_del_mapping(VMS_SELF, mnt);
127     return mnt;
128 }
129
130 void*
131 vmm_ioremap(ptr_t paddr, size_t size);
132
133 void*
134 vmm_next_free(ptr_t start, int options);
135
136 /**
137  * @brief 将当前地址空间的虚拟地址转译为物理地址。
138  *
139  * @param va 虚拟地址
140  * @return void*
141  */
142 ptr_t
143 vmm_v2p(ptr_t va);
144
145 /**
146  * @brief 将指定地址空间的虚拟地址转译为物理地址
147  *
148  * @param mnt 地址空间锚定点
149  * @param va 虚拟地址
150  * @return void*
151  */
152 ptr_t
153 vmm_v2pat(ptr_t mnt, ptr_t va);
154
155 /*
156     表示一个 vmap 区域
157     (One must not get confused with vmap_area in Linux!)
158 */
159 struct vmap_area
160 {
161     ptr_t start;
162     size_t size;
163     pt_attr area_attr;
164 };
165
166 /**
167  * @brief 将连续的物理地址空间映射到内核虚拟地址空间
168  *
169  * @param paddr 物理地址空间的基地址
170  * @param size 物理地址空间的大小
171  * @return void*
172  */
173 void*
174 vmap(ptr_t paddr, size_t size, pt_attr attr, int flags);
175
176 /**
177  * @brief 创建一个 vmap 区域
178  *
179  * @param paddr
180  * @param attr
181  * @return ptr_t
182  */
183 struct vmap_area*
184 vmap_varea(size_t size, pt_attr attr);
185
186 /**
187  * @brief 在 vmap区域内映射一个单页
188  *
189  * @param paddr
190  * @param attr
191  * @return ptr_t
192  */
193 ptr_t
194 vmap_area_page(struct vmap_area* area, ptr_t paddr, pt_attr attr);
195
196 /**
197  * @brief 在 vmap区域删除一个已映射的页
198  *
199  * @param paddr
200  * @return ptr_t
201  */
202 ptr_t
203 vmap_area_rmpage(struct vmap_area* area, ptr_t vaddr);
204
205 #endif /* __LUNAIX_VMM_H */