ZONE_NORMAL 及其与内核/用户页面的关联?

ZONE_NORMAL 及其与内核/用户页面的关联?

图表

上面介绍的是我只有 512 MB 物理内存的情况。到目前为止,我读到的是 ZONE_NORMAL 映射到内核虚拟地址空间,如图所示。本质上我有 512 MB 物理内存,其中 496 MB 的 ZONE_NORMAL 映射到内核虚拟空间。基于这种理解,我的问题如下:

  • ZONE_NORMAL 是否包含仅有的内核空间页面 ?
  • 如果 ZONE_NORMAL 仅由内核页面组成并被映射完全地到内核​​空间虚拟地址范围,用户空间页面位于哪里?物理内存中似乎没有任何空间用于用户空间页面。

我完全混淆了物理内存小于 4GB 的情况,如我提出的这种情况所示。

如果有人能阐明这一点,我将非常感激。

答案1

在 32 位架构上,您有0xffffffff4'294'967'295或 4 GB)线性地址(不是物理空间)来引用物理地址。
即使只有 512 MB 的物理存储(连接到总线的真实 RAM 棒),内核仍将使用4'294'967'295(4 GB) 线性地址来计算物理地址。

Linux 内核将这 4 GB(地址)按 3/1 划分为用户空间(高位内存)和内核空间(低位内存),因此内核空间有1'073'741'823(1 GB)线性地址可供使用。

这 1 GB 的线性地址只能由内核访问,并且会被进一步划分。

区域_DMA:包含小于 16 MB 的内存页框。这用于旧的 ISA 总线,它们只能寻址 RAM 的前 16 MB。

区域_正常:包含 16 MB 及以上且 896 MB 以下的内存页帧,这些是内核可以直接映射/访问的地址。

ZONE_HIGHMEM:包含 896 MB 及以上的内存页框,此边界以上的页框通常不会映射到内核空间,因此内核无法直接访问。来自用户空间的页面框架可以临时或永久映射到此处。

不同区域占用多少实际物理 RAM 空间取决于您运行的进程的形式和数量。

如果您free -ml在控制台中输入,您可以看到使用情况,包括低内存和高内存:

             total       used       free     shared    buffers     cached
Mem:          3022       2116        905          0        105       1342
Low:           839        196        642
High:         2182       1919        263
-/+ buffers/cache:        667       2354
Swap:         2859         93       2766

答案2

同一物理页可以映射到多个虚拟地址。

ZONE_NORMAL 由可以映射的页面组成经过内核。大多数内存不属于内核,但内核需要在某个时刻映射所有内存(不一定同时映射所有内存)。例如,当内核正在处理write系统调用时,它需要从用户提供的缓冲区复制数据,这意味着缓冲区必须映射到内核的虚拟地址空间中。

该图描述了没有高内存的(相对)简单情况。 (如果您使用高端 ARM 设备,现在是开始学习高内存的时候了。)然后内核可以同时映射所有进程内存和所有物理内存。

这是内核代码所看到的虚拟内存重新分区的示例(我不确定确切的数字是否可能,但基本思想应该是正确的)。也就是说,我正在描述内核代码使用的指针的含义。

  • 0x00000000..0x00000fff: 未分配。在此范围内的指针无效。
  • 0x00001000..0xbfffffff:进程内存。这是一个指向进程虚拟地址空间的指针,正在考虑的内核代码正在处理系统调用。该范围内的页面可能未分配,或者可以分配并换入(在这种情况下它也有物理地址),或者可以分配并换出(在这种情况下它没有物理地址) RAM,但它在交换中有一个位置)。
  • 0xc0000000..0xdfffffff: 物理内存。此范围内的指针表示物理地址 p-0xc0000000。该指针的解释实际上并不依赖于MMU。
  • 0xe0000000..0xffefffff: 未分配。在此范围内的指针无效。
  • 0xff000000..0xffffffff: 内核内存。这是指向内核代码或数据的指针。此范围内的页面具有由 MMU 找到的关联物理地址。

我发现Linux 设备驱动程序很好地介绍了 Linux 内核的内部结构。最终,您可能想要转向来源

相关内容