ZONE_NORMAL 和它与内核/用户页面的关联?

The*_*ker 6 linux drivers kernel memory arm

图表

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

  • ZONE_NORMAL 是否包含内核空间页面?
  • 如果ZONE_NORMAL只由内核页,并映射完全到内核空间的虚拟地址范围,你在哪里的用户空间页面获得所在?物理内存中的用户空间页面似乎没有任何空间。

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

如果有人能对此有所了解,我将不胜感激。

Gil*_*il' 1

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

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

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

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

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

我发现《Linux 设备驱动程序》很好地介绍了 Linux 内核的内部结构。最终,您可能想求助于源代码