同步操作将从 OpenHarmony/docs 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
Physical 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.
As 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."
Figure 1 Physical memory usage distribution
The buddy algorithm divides all free page frames into 9 memory block groups, each of which contains 2N page frames. For example, the memory block in group 0 has 20, that is, 1 page frame. The memory block in the eighth group has 28, that is, 256 page frames. Memory blocks of the same size are added to the same linked list for management.
Requesting memory
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 (22) page frames and 1 (20) 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 (20) memory blocks are contiguous, the memory blocks are merged as 2 page frames (21) and inserted to list 2. If the addresses are not contiguous, the two (20) page frames are left in list 0.
Releasing memory
When 12 KiB memory (3 page frames) is released, the 3 page frames can be divided into 2 (21) page frames and 1 (20) 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.
Table 1 Physical memory management module APIs
Use 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.
NOTE:
- APIs used for requesting physical memory can be used only after memory initialization is complete by calling OsSysMemInit.
- The basic unit for memory allocation is page frame, that is, 4 KiB.
- 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.
This example calls APIs to request and release memory, including requesting one and multiple memory pages.
#include "los_vm_phys.h"
#define PHYS_PAGE_SIZE 0x4000
// Request a page.
VOID OsPhysPagesAllocTest3(VOID)
{
PADDR_T newPaddr;
VOID *kvaddr = NULL;
LosVmPage *newPage = NULL;
newPage = LOS_PhysPageAlloc();
if (newPage == NULL) {
printf("LOS_PhysPageAlloc fail\n");
return;
}
printf("LOS_PhysPageAlloc success\n");
newPaddr = VM_PAGE_TO_PHYS(newPage);
kvaddr = OsVmPageToVaddr(newPage);
// Handle the physical memory
// Free the physical memory
LOS_PhysPageFree(newPage);
}
// Request multiple pages that do not need to be contiguous.
VOID OsPhysPagesAllocTest2(VOID)
{
UINT32 sizeCount;
UINT32 count;
UINT32 size = PHYS_PAGE_SIZE;
LosVmPage *vmPageArray[PHYS_PAGE_SIZE >> PAGE_SHIFT] = { NULL };
UINT32 i = 0;
LosVmPage *vmPage = NULL;
PADDR_T pa;
size = LOS_Align(size, PAGE_SIZE);
if (size == 0) {
return;
}
sizeCount = size >> PAGE_SHIFT;
LOS_DL_LIST_HEAD(pageList);
count = LOS_PhysPagesAlloc(sizeCount, &pageList);
if (count < sizeCount) {
printf("failed to allocate enough pages (ask %zu, got %zu)\n", sizeCount, count);
goto ERROR;
}
printf("LOS_PhysPagesAlloc success\n");
while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) {
pa = vmPage->physAddr;
vmPageArray[i++] = vmPage;
// Handle the physical memory
}
// Free the physical memory
for (i = 0; i < sizeCount; ++i) {
LOS_PhysPageFree(vmPageArray[i]);
}
return;
ERROR:
(VOID)LOS_PhysPagesFree(&pageList);
}
// Request multiple contiguous memory pages.
VOID OsPhysPagesAllocTest1(VOID)
{
VOID *ptr = NULL;
LosVmPage *page = NULL;
UINT32 size = PHYS_PAGE_SIZE;
ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT);
if (ptr == NULL) {
printf("LOS_PhysPagesAllocContiguous fail\n");
return;
}
printf("LOS_PhysPagesAllocContiguous success\n");
// Handle the physical memory
// Free the physical memory
page = OsVmVaddrToPage((VOID *)ptr);
LOS_PhysPagesFreeContiguous((VOID *)ptr, size >> PAGE_SHIFT);
}
UINT32 ExamplePhyMemCaseEntry(VOID)
{
OsPhysPagesAllocTest1();
OsPhysPagesAllocTest2();
OsPhysPagesAllocTest3();
return LOS_OK;
}
The development is successful if the return result is as follows:
LOS_PhysPagesAllocContiguous success
LOS_PhysPagesAlloc success
LOS_PhysPageAlloc success
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。