• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 虚拟内存管理<a name="ZH-CN_TOPIC_0000001123800847"></a>
2
3-   [基本概念](#section650193717411)
4-   [运行机制](#section072885512412)
5-   [开发指导](#section20956116050)
6    -   [接口说明](#section166137221657)
7    -   [开发流程](#section8752103914513)
8
9
10## 基本概念<a name="section650193717411"></a>
11
12虚拟内存管理是计算机系统管理内存的一种技术。每个进程都有连续的虚拟地址空间,虚拟地址空间的大小由CPU的位数决定,32位的硬件平台可以提供的最大的寻址空间为0-4GiB。整个4GiB空间分成两部分,LiteOS-A内核占据3GiB的高地址空间,1GiB的低地址空间留给进程使用。各个进程空间的虚拟地址空间是独立的,代码、数据互不影响。
13
14系统将虚拟内存分割为称为虚拟页的内存块,大小一般为4KiB或64KiB,LiteOS-A内核默认的页的大小是4KiB,根据需要可以对MMU(Memory Management Units)进行配置。虚拟内存管理操作的最小单位就是一个页,LiteOS-A内核中一个虚拟地址区间region包含地址连续的多个虚拟页,也可只有一个页。同样,物理内存也会按照页大小进行分割,分割后的每个内存块称为页帧。虚拟地址空间划分:内核态占高地址3GiB\(0x40000000 \~ 0xFFFFFFFF\),用户态占低地址1GiB\(0x01000000 \~ 0x3F000000\),具体见下表,详细可以查看或配置los\_vm\_zone.h15
16**表 1**  内核态地址规划:
17
18<a name="table9988174163613"></a>
19<table><thead align="left"><tr id="row164675173616"><th class="cellrowborder" valign="top" width="19.99%" id="mcps1.2.4.1.1"><p id="p046752361"><a name="p046752361"></a><a name="p046752361"></a>Zone名称</p>
20</th>
21<th class="cellrowborder" valign="top" width="43.13%" id="mcps1.2.4.1.2"><p id="p0461651361"><a name="p0461651361"></a><a name="p0461651361"></a>描述</p>
22</th>
23<th class="cellrowborder" valign="top" width="36.88%" id="mcps1.2.4.1.3"><p id="p446195183611"><a name="p446195183611"></a><a name="p446195183611"></a>属性</p>
24</th>
25</tr>
26</thead>
27<tbody><tr id="row94619516367"><td class="cellrowborder" valign="top" width="19.99%" headers="mcps1.2.4.1.1 "><p id="p1846553363"><a name="p1846553363"></a><a name="p1846553363"></a>DMA zone</p>
28</td>
29<td class="cellrowborder" valign="top" width="43.13%" headers="mcps1.2.4.1.2 "><p id="p3461158364"><a name="p3461158364"></a><a name="p3461158364"></a>供IO设备的DMA使用。</p>
30</td>
31<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p10461152363"><a name="p10461152363"></a><a name="p10461152363"></a>Uncache</p>
32</td>
33</tr>
34<tr id="row246551361"><td class="cellrowborder" valign="top" width="19.99%" headers="mcps1.2.4.1.1 "><p id="p3461259362"><a name="p3461259362"></a><a name="p3461259362"></a>Normal zone</p>
35</td>
36<td class="cellrowborder" valign="top" width="43.13%" headers="mcps1.2.4.1.2 "><p id="p1546056362"><a name="p1546056362"></a><a name="p1546056362"></a>加载内核代码段、数据段、堆和栈的地址区间。</p>
37</td>
38<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p646125143613"><a name="p646125143613"></a><a name="p646125143613"></a>Cache</p>
39</td>
40</tr>
41<tr id="row646165133613"><td class="cellrowborder" valign="top" width="19.99%" headers="mcps1.2.4.1.1 "><p id="p114675183615"><a name="p114675183615"></a><a name="p114675183615"></a>high mem zone</p>
42</td>
43<td class="cellrowborder" valign="top" width="43.13%" headers="mcps1.2.4.1.2 "><p id="p194611583613"><a name="p194611583613"></a><a name="p194611583613"></a>可以分配连续的虚拟内存,但其所映射的物理内存不一定连续。</p>
44</td>
45<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p8461153369"><a name="p8461153369"></a><a name="p8461153369"></a>Cache</p>
46</td>
47</tr>
48</tbody>
49</table>
50
51**表 2**  用户态虚地址规划:
52
53<a name="table19965411366"></a>
54<table><thead align="left"><tr id="row646185183618"><th class="cellrowborder" valign="top" width="20%" id="mcps1.2.4.1.1"><p id="p3466593612"><a name="p3466593612"></a><a name="p3466593612"></a>Zone名称</p>
55</th>
56<th class="cellrowborder" valign="top" width="43.120000000000005%" id="mcps1.2.4.1.2"><p id="p84645143613"><a name="p84645143613"></a><a name="p84645143613"></a>描述</p>
57</th>
58<th class="cellrowborder" valign="top" width="36.88%" id="mcps1.2.4.1.3"><p id="p1146115203615"><a name="p1146115203615"></a><a name="p1146115203615"></a>属性</p>
59</th>
60</tr>
61</thead>
62<tbody><tr id="row7462511363"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.4.1.1 "><p id="p2467516363"><a name="p2467516363"></a><a name="p2467516363"></a>代码段</p>
63</td>
64<td class="cellrowborder" valign="top" width="43.120000000000005%" headers="mcps1.2.4.1.2 "><p id="p7472523618"><a name="p7472523618"></a><a name="p7472523618"></a>用户态代码段地址区间。</p>
65</td>
66<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p14476563611"><a name="p14476563611"></a><a name="p14476563611"></a>Cache</p>
67</td>
68</tr>
69<tr id="row34755153614"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.4.1.1 "><p id="p194735173612"><a name="p194735173612"></a><a name="p194735173612"></a>堆</p>
70</td>
71<td class="cellrowborder" valign="top" width="43.120000000000005%" headers="mcps1.2.4.1.2 "><p id="p114720518362"><a name="p114720518362"></a><a name="p114720518362"></a>用户态堆地址区间。</p>
72</td>
73<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p9474515364"><a name="p9474515364"></a><a name="p9474515364"></a>Cache</p>
74</td>
75</tr>
76<tr id="row9476518368"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.4.1.1 "><p id="p34714516369"><a name="p34714516369"></a><a name="p34714516369"></a>栈</p>
77</td>
78<td class="cellrowborder" valign="top" width="43.120000000000005%" headers="mcps1.2.4.1.2 "><p id="p74705163612"><a name="p74705163612"></a><a name="p74705163612"></a>用户态栈地址区间。</p>
79</td>
80<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p144775143613"><a name="p144775143613"></a><a name="p144775143613"></a>Cache</p>
81</td>
82</tr>
83<tr id="row1047353364"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.4.1.1 "><p id="p1947145163615"><a name="p1947145163615"></a><a name="p1947145163615"></a>共享库</p>
84</td>
85<td class="cellrowborder" valign="top" width="43.120000000000005%" headers="mcps1.2.4.1.2 "><p id="p24745193617"><a name="p24745193617"></a><a name="p24745193617"></a>用于加载用户态共享库的地址区间,包括mmap所映射的区间。</p>
86</td>
87<td class="cellrowborder" valign="top" width="36.88%" headers="mcps1.2.4.1.3 "><p id="p11472510363"><a name="p11472510363"></a><a name="p11472510363"></a>Cache</p>
88</td>
89</tr>
90</tbody>
91</table>
92
93## 运行机制<a name="section072885512412"></a>
94
95虚拟内存管理中,虚拟地址空间是连续的,但是其映射的物理内存并不一定是连续的,如下图所示。可执行程序加载运行,CPU访问虚拟地址空间的代码或数据时存在两种情况:
96
97-   CPU访问的虚拟地址所在的页,如V0,已经与具体的物理页P0做映射,CPU通过找到进程对应的页表条目(详见[虚实映射](kernel-small-basic-inner-reflect.md)),根据页表条目中的物理地址信息访问物理内存中的内容并返回。
98-   CPU访问的虚拟地址所在的页,如V2,没有与具体的物理页做映射,系统会触发缺页异常,系统申请一个物理页,并把相应的信息拷贝到物理页中,并且把物理页的起始地址更新到页表条目中。此时CPU重新执行访问虚拟内存的指令便能够访问到具体的代码或数据。
99
100**图 1**  内存映射示意图<a name="fig144371159135620"></a>
101![](figure/内存映射示意图.png "内存映射示意图")
102
103## 开发指导<a name="section20956116050"></a>
104
105### 接口说明<a name="section166137221657"></a>
106
107**表 3**  虚拟内存管理模块接口
108
109<a name="table1415203765610"></a>
110<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.811281128112812%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>功能分类</p>
111</th>
112<th class="cellrowborder" valign="top" width="29.84298429842984%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>接口<strong id="b197068338312"><a name="b197068338312"></a><a name="b197068338312"></a>名称</strong></p>
113</th>
114<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>描述</p>
115</th>
116</tr>
117</thead>
118<tbody><tr id="row0415737175610"><td class="cellrowborder" rowspan="5" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p4917132105710"><a name="p4917132105710"></a><a name="p4917132105710"></a>获取进程空间系列接口</p>
119</td>
120<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p341513372561"><a name="p341513372561"></a><a name="p341513372561"></a>LOS_CurrSpaceGet</p>
121</td>
122<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p74151037185617"><a name="p74151037185617"></a><a name="p74151037185617"></a>获取当前进程空间结构体指针</p>
123</td>
124</tr>
125<tr id="row1841519376561"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p64151837155618"><a name="p64151837155618"></a><a name="p64151837155618"></a>LOS_SpaceGet</p>
126</td>
127<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p441516379562"><a name="p441516379562"></a><a name="p441516379562"></a>获取虚拟地址对应的进程空间结构体指针</p>
128</td>
129</tr>
130<tr id="row536885134010"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p236819594010"><a name="p236819594010"></a><a name="p236819594010"></a>LOS_GetKVmSpace</p>
131</td>
132<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p736918564019"><a name="p736918564019"></a><a name="p736918564019"></a>获取内核进程空间结构体指针</p>
133</td>
134</tr>
135<tr id="row11567448194112"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p0568204814115"><a name="p0568204814115"></a><a name="p0568204814115"></a>LOS_GetVmallocSpace</p>
136</td>
137<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p05681348204114"><a name="p05681348204114"></a><a name="p05681348204114"></a>获取vmalloc空间结构体指针</p>
138</td>
139</tr>
140<tr id="row1141513373562"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17765212416"><a name="p17765212416"></a><a name="p17765212416"></a>LOS_GetVmSpaceList</p>
141</td>
142<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1972971913115"><a name="p1972971913115"></a><a name="p1972971913115"></a>获取进程空间链表指针</p>
143</td>
144</tr>
145<tr id="row137812054195014"><td class="cellrowborder" rowspan="15" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p15344719152113"><a name="p15344719152113"></a><a name="p15344719152113"></a>虚拟地址区间region相关的操作</p>
146</td>
147<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p97821654195014"><a name="p97821654195014"></a><a name="p97821654195014"></a>LOS_RegionFind</p>
148</td>
149<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p137821854205011"><a name="p137821854205011"></a><a name="p137821854205011"></a>根据起始地址在进程空间内查找是否存在虚拟地址区间</p>
150</td>
151</tr>
152<tr id="row254713575505"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p954785720501"><a name="p954785720501"></a><a name="p954785720501"></a>LOS_RegionRangeFind</p>
153</td>
154<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p20547557175013"><a name="p20547557175013"></a><a name="p20547557175013"></a>根据地址区间在进程空间内查找是否存在虚拟地址区间</p>
155</td>
156</tr>
157<tr id="row1692045119"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1510110115114"><a name="p1510110115114"></a><a name="p1510110115114"></a>LOS_IsRegionFileValid</p>
158</td>
159<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p61011045112"><a name="p61011045112"></a><a name="p61011045112"></a>判断虚拟地址区间region是否与文件关联映射</p>
160</td>
161</tr>
162<tr id="row186701424548"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1967018210546"><a name="p1967018210546"></a><a name="p1967018210546"></a>LOS_RegionAlloc</p>
163</td>
164<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p196701221548"><a name="p196701221548"></a><a name="p196701221548"></a>申请空闲的虚拟地址区间</p>
165</td>
166</tr>
167<tr id="row1955586175412"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p555626195420"><a name="p555626195420"></a><a name="p555626195420"></a>LOS_RegionFree</p>
168</td>
169<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p85568612547"><a name="p85568612547"></a><a name="p85568612547"></a>释放进程空间内特定的region</p>
170</td>
171</tr>
172<tr id="row259111510282"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3591135110288"><a name="p3591135110288"></a><a name="p3591135110288"></a>LOS_RegionEndAddr</p>
173</td>
174<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p4675183817474"><a name="p4675183817474"></a><a name="p4675183817474"></a>获取指定地址区间region的结束地址</p>
175</td>
176</tr>
177<tr id="row12894115716285"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p889418577280"><a name="p889418577280"></a><a name="p889418577280"></a>LOS_RegionSize</p>
178</td>
179<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p68941757112813"><a name="p68941757112813"></a><a name="p68941757112813"></a>获取region的大小</p>
180</td>
181</tr>
182<tr id="row14931456182812"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1293135611287"><a name="p1293135611287"></a><a name="p1293135611287"></a>LOS_IsRegionTypeFile</p>
183</td>
184<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1393185613288"><a name="p1393185613288"></a><a name="p1393185613288"></a>判断是否为文件内存映射</p>
185</td>
186</tr>
187<tr id="row12153854132814"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p115335452819"><a name="p115335452819"></a><a name="p115335452819"></a>LOS_IsRegionPermUserReadOnly</p>
188</td>
189<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1415314545285"><a name="p1415314545285"></a><a name="p1415314545285"></a>判断地址区间是否是用户空间只读属性</p>
190</td>
191</tr>
192<tr id="row29249497282"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1492415495284"><a name="p1492415495284"></a><a name="p1492415495284"></a>LOS_IsRegionFlagPrivateOnly</p>
193</td>
194<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1392434982817"><a name="p1392434982817"></a><a name="p1392434982817"></a>判断地址区间是否是具有私有属性</p>
195</td>
196</tr>
197<tr id="row1233194042814"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3339401289"><a name="p3339401289"></a><a name="p3339401289"></a>LOS_SetRegionTypeFile</p>
198</td>
199<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p193317409285"><a name="p193317409285"></a><a name="p193317409285"></a>设置文件内存映射属性</p>
200</td>
201</tr>
202<tr id="row178971473283"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p4898184782815"><a name="p4898184782815"></a><a name="p4898184782815"></a>LOS_IsRegionTypeDev</p>
203</td>
204<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p11898144722818"><a name="p11898144722818"></a><a name="p11898144722818"></a>判断是否为设备内存映射</p>
205</td>
206</tr>
207<tr id="row11137546152811"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p20137194672812"><a name="p20137194672812"></a><a name="p20137194672812"></a>LOS_SetRegionTypeDev</p>
208</td>
209<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p81384462287"><a name="p81384462287"></a><a name="p81384462287"></a>设置设备内存映射属性</p>
210</td>
211</tr>
212<tr id="row1023564216285"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p92351842162819"><a name="p92351842162819"></a><a name="p92351842162819"></a>LOS_IsRegionTypeAnon</p>
213</td>
214<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p6235842132818"><a name="p6235842132818"></a><a name="p6235842132818"></a>判断是否为匿名映射</p>
215</td>
216</tr>
217<tr id="row1646364402813"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p44631644152814"><a name="p44631644152814"></a><a name="p44631644152814"></a>LOS_SetRegionTypeAnon</p>
218</td>
219<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p174631844182818"><a name="p174631844182818"></a><a name="p174631844182818"></a>设置匿名映射属性</p>
220</td>
221</tr>
222<tr id="row038233717288"><td class="cellrowborder" rowspan="5" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p6820331185317"><a name="p6820331185317"></a><a name="p6820331185317"></a>地址校验</p>
223</td>
224<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p838383720282"><a name="p838383720282"></a><a name="p838383720282"></a>LOS_IsUserAddress</p>
225</td>
226<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p12383837102818"><a name="p12383837102818"></a><a name="p12383837102818"></a>判断地址是否在用户态空间</p>
227</td>
228</tr>
229<tr id="row61506354284"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p2151113517288"><a name="p2151113517288"></a><a name="p2151113517288"></a>LOS_IsUserAddressRange</p>
230</td>
231<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p615123552814"><a name="p615123552814"></a><a name="p615123552814"></a>判断地址区间是否在用户态空间</p>
232</td>
233</tr>
234<tr id="row18301515194210"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p19301141519421"><a name="p19301141519421"></a><a name="p19301141519421"></a>LOS_IsKernelAddress</p>
235</td>
236<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p730110154427"><a name="p730110154427"></a><a name="p730110154427"></a>判断地址是否在内核空间</p>
237</td>
238</tr>
239<tr id="row191211718204213"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1112121812423"><a name="p1112121812423"></a><a name="p1112121812423"></a>LOS_IsKernelAddressRange</p>
240</td>
241<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p6122101814219"><a name="p6122101814219"></a><a name="p6122101814219"></a>判断地址区间是否在内核空间</p>
242</td>
243</tr>
244<tr id="row774964092115"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17152102415416"><a name="p17152102415416"></a><a name="p17152102415416"></a>LOS_IsRangeInSpace</p>
245</td>
246<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p115218248547"><a name="p115218248547"></a><a name="p115218248547"></a>判断地址区间是否在进程空间内</p>
247</td>
248</tr>
249<tr id="row179196525521"><td class="cellrowborder" rowspan="3" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p153501191535"><a name="p153501191535"></a><a name="p153501191535"></a>vmalloc操作</p>
250</td>
251<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p152945155531"><a name="p152945155531"></a><a name="p152945155531"></a>LOS_VMalloc</p>
252</td>
253<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1229461512535"><a name="p1229461512535"></a><a name="p1229461512535"></a>vmalloc申请内存</p>
254</td>
255</tr>
256<tr id="row1934135935211"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p162941115155315"><a name="p162941115155315"></a><a name="p162941115155315"></a>LOS_VFree</p>
257</td>
258<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p12294171516536"><a name="p12294171516536"></a><a name="p12294171516536"></a>vmalloc释放内存</p>
259</td>
260</tr>
261<tr id="row944214919304"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p644229163016"><a name="p644229163016"></a><a name="p644229163016"></a>LOS_IsVmallocAddress</p>
262</td>
263<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1344220993011"><a name="p1344220993011"></a><a name="p1344220993011"></a>判断地址是否是通过vmalloc申请的</p>
264</td>
265</tr>
266<tr id="row72131845145315"><td class="cellrowborder" rowspan="4" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p84847816543"><a name="p84847816543"></a><a name="p84847816543"></a>内存申请系列接口</p>
267</td>
268<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p8787345546"><a name="p8787345546"></a><a name="p8787345546"></a>LOS_KernelMalloc</p>
269</td>
270<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p17787444543"><a name="p17787444543"></a><a name="p17787444543"></a>申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页</p>
271</td>
272</tr>
273<tr id="row48491549145311"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p14787149541"><a name="p14787149541"></a><a name="p14787149541"></a>LOS_KernelMallocAlign</p>
274</td>
275<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p478719411543"><a name="p478719411543"></a><a name="p478719411543"></a>申请具有对齐属性的内存,申请规则:申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页</p>
276</td>
277</tr>
278<tr id="row151093538536"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p15787134185412"><a name="p15787134185412"></a><a name="p15787134185412"></a>LOS_KernelFree</p>
279</td>
280<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p878712410546"><a name="p878712410546"></a><a name="p878712410546"></a>释放内核堆内存</p>
281</td>
282</tr>
283<tr id="row5126856205319"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p197871646545"><a name="p197871646545"></a><a name="p197871646545"></a>LOS_KernelRealloc</p>
284</td>
285<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p378813416547"><a name="p378813416547"></a><a name="p378813416547"></a>重新分配内核内存空间</p>
286</td>
287</tr>
288<tr id="row12397132718549"><td class="cellrowborder" rowspan="5" valign="top" width="12.811281128112812%" headers="mcps1.2.4.1.1 "><p id="p112971954115419"><a name="p112971954115419"></a><a name="p112971954115419"></a>其他</p>
289</td>
290<td class="cellrowborder" valign="top" width="29.84298429842984%" headers="mcps1.2.4.1.2 "><p id="p2777034145414"><a name="p2777034145414"></a><a name="p2777034145414"></a>LOS_PaddrQuery</p>
291</td>
292<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p13777834115413"><a name="p13777834115413"></a><a name="p13777834115413"></a>根据虚拟地址获取对应的物理地址</p>
293</td>
294</tr>
295<tr id="row5558122119542"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p9558421155418"><a name="p9558421155418"></a><a name="p9558421155418"></a>LOS_VmSpaceFree</p>
296</td>
297<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p755852119545"><a name="p755852119545"></a><a name="p755852119545"></a>释放进程空间,包括虚拟内存区间、页表等信息</p>
298</td>
299</tr>
300<tr id="row15860142919544"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p168603298547"><a name="p168603298547"></a><a name="p168603298547"></a>LOS_VmSpaceReserve</p>
301</td>
302<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p12860429185410"><a name="p12860429185410"></a><a name="p12860429185410"></a>在进程空间中预留一块内存空间</p>
303</td>
304</tr>
305<tr id="row394217543569"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p11943125419566"><a name="p11943125419566"></a><a name="p11943125419566"></a>LOS_VaddrToPaddrMmap</p>
306</td>
307<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p16943954105613"><a name="p16943954105613"></a><a name="p16943954105613"></a>将指定长度的物理地址区间与虚拟地址区间做映射,需提前申请物理地址区间</p>
308</td>
309</tr>
310<tr id="row18527155718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p118526110579"><a name="p118526110579"></a><a name="p118526110579"></a>LOS_UserSpaceVmAlloc</p>
311</td>
312<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1485214117575"><a name="p1485214117575"></a><a name="p1485214117575"></a>根据地址、大小、权限等信息在用户进程空间内申请地址区间region</p>
313</td>
314</tr>
315</tbody>
316</table>
317
318### 开发流程<a name="section8752103914513"></a>
319
320虚拟内存相关接口的使用:
321
3221.  根据进程空间获取的系列接口可以得到进程空间结构体,进而可以读取结构体相应信息。
3232.  对虚拟地址区间做相关操作:
324    -   通过LOS\_RegionAlloc申请虚拟地址区间;
325
326    -   通过LOS\_RegionFind、LOS\_RegionRangeFind可以查询是否存在相应的地址区间;
327    -   通过LOS\_RegionFree释放虚拟地址区间。
328
3293.  vmalloc接口及内存申请系列接口可以在内核中根据需要申请内存。
330
331>![](../public_sys-resources/icon-note.gif) **说明:**
332>内存申请系列接口申请的内存要求物理内存是连续的,当系统内存无法满足大块连续内存的申请条件时会申请失败,一般适用于小块内存的申请;vmalloc相关接口申请的内存可以获得不连续的物理内存,但其是以页(当前系统一个页为4096字节)为单位的,当需要申请以页为整数倍的内存时可以通过vmalloc申请,例如文件系统中文件读取需要较大的缓存,便可以通过vmalloc相关接口申请内存。
333
334