当前位置:首页 > 内存 > 正文

Linux内核内存管理

  • 内存
  • 2024-04-28 22:25:36
  • 2563

一、linux内存管理--linux内核高端内存Linux内核地址映射模型
x86
CPU使用段页地址映射模型。进程代码中的地址就是逻辑地址,映射段页地址后,才真正访问到物理内存。
段页机制如下图。
Linux内核地址空间的划分
通常32位Linux内核地址空间分为0~3G作为用户空间,3~4G作为内核空间。注意,这是32位内核地址空间的一部分,和64位内核地址空间的一部分是不同的。
Linux内核中花式内存的由来
当内核模块代码或线程访问内存时,代码中的内存地址都是逻辑地址,与实际的物理内存地址一一对应。-需要一次地址映射,例如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,...
...,对应关系逻辑地址和物理地址之间的关系是
物理地址
=
逻辑地址
0xC0000000
逻辑地址物理内存地址0xc00000000×00xc00000010×10xc0000000c2×10xc0000000c…

0xe00000000×20000000……0xffffffff0×40000000
??
显然内核地址空间0xc0000000
~
0xffffffff不能用于简洁的地址映射。因此,x86架构将内核地址空间分为三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM是高端内存,这就是高端内存概念的由来。
在x86结构中,三种类型的区域如下:
ZONE_DMA
从内存开始16MB
ZONE_NORMAL
16MB~896MB
ZONE_HIGHMEM
896MB
~
结束
了解Linux内核中的花式内存
前面我们解释了花式内存的由来。
Linux将内核地址空间分为三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高位内存HIGH_MEM地址空间范围为0xF8000000
~
0xFFFFFFFF(896MB~1024MB)。那么内核是如何利用128MB的花式内存地址空间来实现对所有物理内存的访问的呢?
当内核要访问物理地址高于896MB的内存时,会在地址空间范围0xF8000000
~
0xFFFFFFFF中寻找相应大小的空闲逻辑地址空间并借位暂时吧。借用这个逻辑地址空间,并将其映射到你想要访问的物理内存上(即填充PTE内核页表,暂时使用,用后归还)。这样其他人也可以借用这个地址空间来访问其他物理内存,实现使用有限的地址空间来访问所有物理内存。如下所示。
例如,内核要访问从2G开始的1MB物理内存,即物理地址范围为0×80000000
~
0x800FFFFF。访问之前,先找到1MB空闲地址空间,假设找到的空闲地址空间为0xF8700000
~
0xF87FFFFF,用这1MB逻辑地址空间映射到物理地址空间0×80000000
~
内存0x800FFFFF。映射关系如下:
物理内存地址0xF87000000×800000000xF87000010×800000010xF87000020×80000002…
…0xF870FFFFF0x0xF870FFFFF0x000
~
0x800的逻辑地址FFFFF之后,内核线性空间0xF8700000
~
0xF87FFFFF已发出。这样,其他进程或代码也可以使用地址0xF8700000
~
0xF87FFFFF来访问其他物理内存。
从上面的描述,我们可以知道花式内存最基本的思想:借用一部分地址空间,创建一个临时地址映射,当到达这个地址空间时释放它,可以回收并访问所有物理内存。
看到这里,有人不禁要问:如果一个内核进程或模块继续占用某个逻辑地址空间而不释放怎么办?如果真的出现这种情况,内核花式内存地址空间就会越来越紧张,如果被占用而不清除,即使不映射到物理内存也将无法访问。