Linux 上的高内存和低内存是什么?

Linux 上的高内存和低内存是什么?

我对 Highmem 和 Lowmem 之间的区别感兴趣:

  1. 为什么会有这样的差别呢?
  2. 这样做我们能得到什么?
  3. 各有什么特点?

答案1

在 32 位架构上,寻址 RAM 的地址空间范围为:

0x00000000 - 0xffffffff

4'294'967'295(4 GB)。

Linux 内核将其 3/1 (也可能是 2/2 或 1/3 1)分别分成用户空间(高内存)和内核空间(低内存)。

用户空间范围:

0x00000000 - 0xbfffffff

每个新生成的用户进程都会在该区域内获得一个地址(范围)。用户进程通常是不可信的,因此被禁止访问内核空间。此外,它们被认为是非紧急的,作为一般规则,内核尝试推迟向这些进程分配内存。

内核空间范围:

0xc0000000 - 0xffffffff

内核进程在这里获取其地址(范围)。内核可以直接访问这 1 GB 地址(当然,不是完整的 1 GB,还有 128 MB 保留用于高端内存访问)。

在内核空间中生成的进程是可信的、紧急的并且假定没有错误,内存请求会立即得到处理。

如果愿意,每个内核进程也可以访问用户空间范围。为了实现这一点,内核将用户空间(高位内存)的地址映射到内核空间(低位内存),上面提到的 128 MB 是专门为此保留的。


1分割是3/1、2/2还是1/3由CONFIG_VMSPLIT_...选项控制;您可以检查一下,/boot/config*看看为您的内核选择了哪个选项。

答案2

第一个参考文献是Linux 设备驱动程序(可在线或以书籍形式获取),特别是第15章其中有一个关于该主题的部分。

在理想的情况下,每个系统组件都能够映射它需要访问的所有内存。 Linux 和大多数操作系统上的进程都是这种情况:32 位进程只能访问略小于 2^32 字节的虚拟内存(实际上,在典型的 Linux 32 位架构上约为 3GB)。对于内核来说,这变得很困难,它需要能够映射正在执行系统调用的进程的完整内存,加上整个物理内存,以及任何其他内存映射的硬件设备。

所以当32位内核需要映射超过4GB内存时,必须编译为高内存支持。高端内存是没有永久映射到内核地址空间的内存。 (低内存则相反:它总是被映射,因此您只需通过取消引用指针即可在内核中访问它。)

当您从内核代码访问高位内存时,您需要kmap首先调用,以从页数据结构()中获取指针struct pagekmap无论页面位于高内存还是低内存,调用都有效。还有kmap_atomic一种增加了约束,但在多处理器机器上效率更高,因为它使用更细粒度的锁定。通过获得的指针kmap是一种资源:它占用了地址空间。一旦完成,您必须调用kunmap(或kunmap_atomic) 来释放该资源;那么该指针就不再有效,并且在再次调用之前无法访问该页面的内容kmap

答案3

这与Linux内核有关;我不确定 Unix 内核是如何处理这个问题的。

高内存是用户空间程序可以寻址的内存段。它不能触及低内存。

低内存是 Linux 内核可以直接寻址的内存段。如果内核必须访问高端内存,它必须首先将其映射到自己的地址空间。

最近推出了一个补丁,可以让您控制片段的位置。权衡是您可以从用户空间中取出可寻址内存,以便内核可以拥有更多在使用前不必映射的内存。

其他资源:

答案4

对于那些在 Linux 内核内存空间上下文中寻找解释的人来说,请注意两个相互矛盾的定义高/低内存分割(不幸的是没有标准,必须在上下文中解释):

  • “高端内存”定义为内核空间的总和虚拟的记忆。这是一个只有内核可以访问的区域,包含所有大于或等于 的虚拟地址PAGE_OFFSET。因此,“低内存”指的是剩余地址的区域,其对应于每个用户进程可访问的用户空间内存。

    例如:在默认为 的 32 位 x86 上PAGE_OFFSET,这意味着高端内存是任何地址ADDRADDR ≥ 0xC0000000 = PAGE_OFFSET即更高的 1 GB)。

    这就是 Linux 32 位进程通常限制为 3 GB 的原因。注意PAGE_OFFSET不能直接配置,依赖于可配置VMSPLIT_x选项(来源)。

    总结一下:在 32 位架构中,虚拟内存默认分为较低的 3 GB(用户空间)和较高的 1 GB(内核空间)。

    对于 64 位,PAGE_OFFSET不可配置,并且取决于有时在内核加载期间运行时检测到的架构细节。

    在 x86_64 上,PAGE_OFFSET用于0xffff8880000000004 级分页(典型)和0xff110000000000005 级分页(来源)。对于 ARM64,这通常是0x8000000000000000.但请注意,如果启用了 KASLR,则该值是故意不可预测的。


  • “高级内存”定义为身体的无法与内核虚拟内存的其余部分连续映射的内存。内核虚拟地址空间的一部分可以作为单个连续块映射到所谓的物理“低内存”中。要完全理解这意味着什么,需要对 Linux 虚拟内存空间有更深入的了解。我建议通过这些幻灯片

    从幻灯片来看:

    大内存图

    这种“高/低内存”划分仅适用于安装的物理 RAM 大小相对较高(超过约 1 GB)的 32 位架构。否则,即当物理地址空间较小(<1GB)或虚拟内存空间较大(64位)时,可以从内核虚拟内存空间访问整个物理空间。在这种情况下,所有物理内存都被视为“低内存”。

    最好根本不存在高端内存,因为整个物理空间可以直接从内核访问,这使得内存管理更加简单和高效。这在处理 DMA(通常需要物理上连续的内存)时尤其重要。

    另请参阅@gilles 的回答

相关内容