DragonOS/docs/kernel/memory_management/allocate-memory.md

2.4 KiB
Raw Permalink Blame History

内存分配指南

本文将讲述如何在内核中进行内存分配。在开始之前请您先了解一个基本点DragonOS的内核使用4KB的页来管理内存并且具有伙伴分配器和slab分配器。并且对用户空间、内核空间均具有特定的管理机制。

1. 安全的分配内存

在默认情况下KernelAllocator被绑定为全局内存分配器它会根据请求分配的内存大小自动选择使用slab还是伙伴分配器。因此在内核中使用Rust原生的 内存分配函数,或者是创建一个Box对象等等,都是安全的。

2. 手动管理页帧

:::{warning} 请格外小心! 手动管理页帧脱离了Rust的内存安全机制因此可能会造成内存泄漏或者是内存错误。 :::

  在某些情况下,我们需要手动分配页帧。例如,我们需要在内核中创建一个新的页表,或者是在内核中创建一个新的地址空间。这时候,我们需要手动分配页帧。使用LockedFrameAllocatorallocate()函数能够分配在物理地址上连续的页帧。请注意由于底层使用的是buddy分配器因此页帧数目必须是2的n次幂且最大大小不超过1GB。

  当需要释放页帧的时候,使用LockedFrameAllocatordeallocate()函数,或者是deallocate_page_frames()函数,能够释放在物理地址上连续的页帧。

  当您需要映射页帧的时候,可使用KernelMapper::lock()函数获得一个内核映射器对象然后进行映射。由于KernelMapper是对PageMapper的封装因此您在获取KernelMapper之后可以使用PageMapper相关接口对内核空间的映射进行管理。

:::{warning} 千万不要 使用KernelMapper去映射用户地址空间的内存这会使得这部分内存脱离用户地址空间的管理从而导致内存错误。 :::

3. 为用户程序分配内存

  在内核中,您可以使用用户地址空间结构体(AddressSpace)的mmap(),map_anonymous()等函数为用户程序分配内存。这些函数会自动将用户程序的内存映射到用户地址空间中并且会自动创建VMA结构体。您可以使用AddressSpacemunmap()函数将用户程序的内存从用户地址空间中解除映射并且销毁VMA结构体。调整权限等操作可以使用AddressSpacemprotect()函数。