Linux内存管理

内存管理的一些概念

换页

当物理内存不足时,需要将一些物理页写入磁盘,并在页表中修改该物理页和虚拟页的映射状态,表明已被换出到磁盘。之后标记该物理页空闲并分配即可。当需要该物理页时,访存时会发生缺页异常,会从磁盘上将该页取回。

伙伴系统

伙伴系统用于分配连续的物理内存页。它将物理内存划分成连续的块,以块为单位进行分配。每个块是一个或多个连续的物理页组成,物理页的数量必须是2的倍数。

当要分配m个页时,伙伴系统会寻找大小为$2^n$的块,且满足$2^{n-1}<m\le 2^n$,也就是大小最合适的块。如果找不到的话,大块可以一分为二,分成两个或为伙伴的小块,且可以递归继续往下分。

回收块时,伙伴系统会找到它的伙伴块,如果伙伴块空闲,则会递归地向上合并。

知识点

进程的虚拟内存用vm_area_struct描述。

  • ARM64内存分布

虚拟地址空间分为两个空间:

用户空间:0x0000 0000 0000 0000 -- 0x0000 FFFF FFFF FFFF

内核空间:0xFFFF 0000 0000 0000 -- 0xFFFF FFFF FFFF FFFF

  • 物理内存映射

Linux会映射两次物理内存到内核虚拟空间。第一次映射内核镜像的物理内存区域到内核空间的vmalloc区域。第二次将整个物理内存线性映射到内核虚拟空间的0xFFFF8000...000开始的位置

  • zone

内存管理区,内核通过内存管理区来管理内存。通常,内核的zone可分为ZONE_DMA, ZONE_DMA32, ZONE_NORMAL和ZONE_HIGHMEM。对于qemu虚拟机,只有DMA32,用于低4G内存的管理。

mem_map全局变量是个page数组,可以实现快速地虚拟地址到物理地址的映射(内核空间的线性映射)

  • __pa__va

用于转换物理地址和虚拟地址(线性映射的内核地址空间区域)。分别调用了__virt_to_phys__phys_