• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Physical Memory Management
2
3
4## Basic Concepts<a name="section210891719217"></a>
5
6Physical memory is one of the most important resources on a computer. It is the memory space that is provided by the physical memory devices and can be directly addressed through the CPU bus. The physical memory provides temporary storage space for the OS and programs. The LiteOS-A kernel manages the physical memory via memory paging. Except the memory occupied by the kernel heap, other available memory is divided into page frames in the unit of 4 KiB. Memory is allocated and reclaimed by page frame. The kernel uses the buddy algorithm to manage free pages to reduce the fragmentation rate and improve the memory allocation and release efficiency. However, a small block may block the merge of a large block, causing a failure to allocate a large memory block.
7
8## Working Principles<a name="section111355315213"></a>
9
10As shown in the following figure, the physical memory distribution of the LiteOS-A kernel consists of the kernel image, kernel heap, and physical pages. For details about the kernel heap, see "Heap Memory Management."
11
12**Figure  1**  Physical memory usage distribution<a name="fig3648124205514"></a>
13![](figures/physical-memory-usage-distribution.png "physical-memory-usage-distribution")
14
15The buddy algorithm divides all free page frames into 9 memory block groups, each of which contains 2<sup>N</sup>  page frames. For example, the memory block in group 0 has 2<sup>0</sup>, that is, 1 page frame. The memory block in the eighth group has 2<sup>8</sup>, that is, 256 page frames. Memory blocks of the same size are added to the same linked list for management.
16
17-   Requesting memory
18
19    When 12 KiB memory \(3 page frames\) is requested, the list in group 3 \(with 8 page frames\) meets the requirement. After 12 KiB memory is allocated, 20 KiB memory \(5 page frames\) is left. The 5 page frames can be divided into 4 \(2<sup>2</sup>\) page frames and 1 \(2<sup>0</sup>\) page frame. The 4 page frames have no buddy in the list, and therefore are inserted into list 2. The 1 page frame has a buddy in list 0. If the addresses of the two \(2<sup>0</sup>\) memory blocks are contiguous, the memory blocks are merged as 2 page frames \(2<sup>1</sup>\) and inserted to list 2. If the addresses are not contiguous, the two \(2<sup>0</sup>\) page frames are left in list 0.
20
21    **Figure  2**  Requesting memory<a name="fig1319620135615"></a>
22    ![](figures/requesting-memory.png "requesting-memory")
23
24
25-   Releasing memory
26
27    When 12 KiB memory \(3 page frames\) is released, the 3 page frames can be divided into 2 \(2<sup>1</sup>\) page frames and 1 \(2<sup>0</sup>\) page frame. The 2 page frames can be merged with the memory in linked list 1 if their addresses are contiguous and inserted to list 2. The one page frame can be merged with the memory in linked list 0 if their addresses are contiguous and inserted to list 1. In this way, the memory is released based on the buddy mechanism.
28
29    **Figure  3**  Releasing memory<a name="fig44001027165614"></a>
30    ![](figures/releasing-memory.png "releasing-memory")
31
32
33## Development Guidelines<a name="section393116496217"></a>
34
35### Available APIs<a name="section13210155619214"></a>
36
37**Table  1**  Physical memory management module APIs
38
39<a name="table1415203765610"></a>
40<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.821282128212822%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a><strong id="b1878413376595"><a name="b1878413376595"></a><a name="b1878413376595"></a>Function</strong></p>
41</th>
42<th class="cellrowborder" valign="top" width="29.832983298329836%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a><strong id="b395935974010"><a name="b395935974010"></a><a name="b395935974010"></a>API</strong></p>
43</th>
44<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><strong id="b5959320418"><a name="b5959320418"></a><a name="b5959320418"></a>Description</strong></p>
45</th>
46</tr>
47</thead>
48<tbody><tr id="row11567448194112"><td class="cellrowborder" rowspan="3" valign="top" width="12.821282128212822%" headers="mcps1.2.4.1.1 "><p id="p1377313451287"><a name="p1377313451287"></a><a name="p1377313451287"></a>Requesting physical memory</p>
49</td>
50<td class="cellrowborder" valign="top" width="29.832983298329836%" headers="mcps1.2.4.1.2 "><p id="p69501257634"><a name="p69501257634"></a><a name="p69501257634"></a>LOS_PhysPageAlloc</p>
51</td>
52<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p17950155714310"><a name="p17950155714310"></a><a name="p17950155714310"></a>Requests a physical page.</p>
53</td>
54</tr>
55<tr id="row1877155711548"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p687795718546"><a name="p687795718546"></a><a name="p687795718546"></a>LOS_PhysPagesAlloc</p>
56</td>
57<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p11877957115413"><a name="p11877957115413"></a><a name="p11877957115413"></a>Requests a physical page and adds it to the corresponding linked list.</p>
58</td>
59</tr>
60<tr id="row1141513373562"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1525917111411"><a name="p1525917111411"></a><a name="p1525917111411"></a>LOS_PhysPagesAllocContiguous</p>
61</td>
62<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p72594111245"><a name="p72594111245"></a><a name="p72594111245"></a>Requests memory of contiguous pages.</p>
63</td>
64</tr>
65<tr id="row11129518231"><td class="cellrowborder" rowspan="3" valign="top" width="12.821282128212822%" headers="mcps1.2.4.1.1 "><p id="p329691015710"><a name="p329691015710"></a><a name="p329691015710"></a>Releasing physical memory</p>
66</td>
67<td class="cellrowborder" valign="top" width="29.832983298329836%" headers="mcps1.2.4.1.2 "><p id="p836211258313"><a name="p836211258313"></a><a name="p836211258313"></a>LOS_PhysPageFree</p>
68</td>
69<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p183626251933"><a name="p183626251933"></a><a name="p183626251933"></a>Releases a physical page.</p>
70</td>
71</tr>
72<tr id="row171671014107"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p368411237415"><a name="p368411237415"></a><a name="p368411237415"></a>LOS_PhysPagesFree</p>
73</td>
74<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p12684112320411"><a name="p12684112320411"></a><a name="p12684112320411"></a>Releases the physical pages added to a linked list.</p>
75</td>
76</tr>
77<tr id="row13796135518114"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p379616558114"><a name="p379616558114"></a><a name="p379616558114"></a>LOS_PhysPagesFreeContiguous</p>
78</td>
79<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1879675510114"><a name="p1879675510114"></a><a name="p1879675510114"></a>Releases memory of contiguous pages.</p>
80</td>
81</tr>
82<tr id="row757517464414"><td class="cellrowborder" rowspan="2" valign="top" width="12.821282128212822%" headers="mcps1.2.4.1.1 "><p id="p128501418185714"><a name="p128501418185714"></a><a name="p128501418185714"></a>Querying memory address</p>
83</td>
84<td class="cellrowborder" valign="top" width="29.832983298329836%" headers="mcps1.2.4.1.2 "><p id="p147379529411"><a name="p147379529411"></a><a name="p147379529411"></a>LOS_VmPageGet</p>
85</td>
86<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1573711521144"><a name="p1573711521144"></a><a name="p1573711521144"></a>Obtains the physical page structure pointer based on the physical address.</p>
87</td>
88</tr>
89<tr id="row20508104412412"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1124573417"><a name="p1124573417"></a><a name="p1124573417"></a>LOS_PaddrToKVaddr</p>
90</td>
91<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p71217579414"><a name="p71217579414"></a><a name="p71217579414"></a>Obtains the kernel virtual address based on the physical address.</p>
92</td>
93</tr>
94</tbody>
95</table>
96
97### How to Develop<a name="section178441091231"></a>
98
99Use different APIs to request memory. Heap management APIs are recommended for requesting small amount of memory. Physical memory management APIs are recommended for requesting 4 KiB or larger memory.
100
101>![](../public_sys-resources/icon-note.gif) **NOTE:**
102>-   APIs used for requesting physical memory can be used only after memory initialization is complete by calling  **OsSysMemInit**.
103>-   The basic unit for memory allocation is page frame, that is, 4 KiB.
104>-   To leave contiguous memory blocks for the modules that demand them, use  **LOS\_PhysPagesAllocContiguous**  to request contiguous memory blocks and use  **LOS\_PhysPagesAlloc**  to request memory blocks that are not contiguous.
105
106### Development Example<a name="section1258174015319"></a>
107
108This example calls APIs to request and release memory, including requesting one and multiple memory pages.
109
110```
111#include "los_vm_phys.h"
112
113#define PHYS_PAGE_SIZE 0x4000
114
115// Request a page.
116VOID OsPhysPagesAllocTest3(VOID)
117{
118    PADDR_T newPaddr;
119    VOID *kvaddr = NULL;
120    LosVmPage *newPage = NULL;
121
122    newPage = LOS_PhysPageAlloc();
123    if (newPage == NULL) {
124        printf("LOS_PhysPageAlloc fail\n");
125        return;
126    }
127    printf("LOS_PhysPageAlloc success\n");
128
129    newPaddr = VM_PAGE_TO_PHYS(newPage);
130    kvaddr = OsVmPageToVaddr(newPage);
131
132    // Handle the physical memory
133
134    // Free the physical memory
135    LOS_PhysPageFree(newPage);
136}
137
138// Request multiple pages that do not need to be contiguous.
139VOID OsPhysPagesAllocTest2(VOID)
140{
141    UINT32 sizeCount;
142    UINT32 count;
143    UINT32 size = PHYS_PAGE_SIZE;
144    LosVmPage *vmPageArray[PHYS_PAGE_SIZE >> PAGE_SHIFT] = { NULL };
145    UINT32 i = 0;
146    LosVmPage *vmPage = NULL;
147    PADDR_T pa;
148
149    size = LOS_Align(size, PAGE_SIZE);
150    if (size == 0) {
151        return;
152    }
153    sizeCount = size >> PAGE_SHIFT;
154
155    LOS_DL_LIST_HEAD(pageList);
156
157    count = LOS_PhysPagesAlloc(sizeCount, &pageList);
158    if (count < sizeCount) {
159        printf("failed to allocate enough pages (ask %zu, got %zu)\n", sizeCount, count);
160        goto ERROR;
161    }
162    printf("LOS_PhysPagesAlloc success\n");
163    while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) {
164        pa = vmPage->physAddr;
165        vmPageArray[i++] = vmPage;
166        // Handle the physical memory
167    }
168
169    // Free the physical memory
170    for (i = 0; i < sizeCount; ++i) {
171        LOS_PhysPageFree(vmPageArray[i]);
172    }
173
174    return;
175
176ERROR:
177    (VOID)LOS_PhysPagesFree(&pageList);
178}
179
180// Request multiple contiguous memory pages.
181VOID OsPhysPagesAllocTest1(VOID)
182{
183    VOID *ptr = NULL;
184    LosVmPage *page = NULL;
185    UINT32 size = PHYS_PAGE_SIZE;
186
187    ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT);
188    if (ptr == NULL) {
189        printf("LOS_PhysPagesAllocContiguous fail\n");
190        return;
191    }
192
193    printf("LOS_PhysPagesAllocContiguous success\n");
194
195    // Handle the physical memory
196
197    // Free the physical memory
198    page = OsVmVaddrToPage((VOID *)ptr);
199    LOS_PhysPagesFreeContiguous((VOID *)ptr, size >> PAGE_SHIFT);
200}
201
202UINT32 ExamplePhyMemCaseEntry(VOID)
203{
204    OsPhysPagesAllocTest1();
205    OsPhysPagesAllocTest2();
206    OsPhysPagesAllocTest3();
207    return LOS_OK;
208}
209```
210
211### Verification<a name="section515091342819"></a>
212
213The development is successful if the return result is as follows:
214
215```
216LOS_PhysPagesAllocContiguous success
217LOS_PhysPagesAlloc success
218LOS_PhysPageAlloc success
219```
220
221