Linux 内核中的内存映射 - 使用 vamlloc() 和 kmalloc()
Memory Mapping in Linux Kernel - use of vamlloc() and kmalloc()
考虑一个 32 位 x86 Linux 系统,具有 4 GB RAM 内存,因此如书中所述以及在许多论坛上,内存映射如下:
- 内核逻辑地址 - 高达 896 MB - 这是一对一映射的,可以使用 kmalloc 分配().
- 内核虚拟地址-128MB(896MB以上-内核逻辑地址)-使用vmalloc()[分配=41=] 并分配虚拟连续但物理上(分散在 RAM 内)非连续内存页。
有几点我不能完全理解并需要澄清。
我的理解是,当使用kmalloc()分配内存时,它总是来自RAM中的0到896MB,而不是超出。
当我们使用 vmalloc() 分配内存时,分配的内存是否在 RAM 中的 896MB 到 4GB 范围内?还是仅在 RAM 中从 896MB 到 1GB 范围分配?
当我们说内核只有1GB的虚拟地址时space,是否意味着内核不能访问超过1GB的RAM?如果可以那么它是如何完成的? 128MB的内核虚拟地址space是否用于此目的?
请帮忙。
理论上有3种不同"memory managers"。一个管理物理 RAM(主要跟踪空闲物理 RAM 的页面),一个管理虚拟 space(映射到每个虚拟地址 space 的内容,其中使用固定大小的块 - 页面大小),第三个管理 "heap"(允许将更大的虚拟地址 space 分成任意大小的部分)。
最初; Linux 内核试图使用它的内核 "heap" 来管理这三个截然不同的东西。通过将 "all RAM" 线性映射到内核 space,他们绕过了管理内核虚拟内存的需要,并最终在内核 space 中的虚拟地址和物理地址(例如 "physical = virtual - base"), 并且通过分配 "heap" 你也分配了物理内存。
这本来很好,因为当时计算机很少有超过 128 MiB 的 RAM(而且 Linus 没想到内核会存在很长时间,因为 GNU 正计划切换到 Hurd "soon" ),内核 space 明显大于 "all RAM"。随着 RAM 数量的增加,它变成了一个问题 -"all RAM" 变得比内核 space 大,所以 "use heap to manage 3 very different things" 无法工作。
当然,一旦它成为一个问题,很多内核的代码都依赖于 "kmalloc to allocate physical memory",这使得修复这个问题变得太难了。相反,他们将物理内存分成 2 个区域——一个区域由 "kmalloc" 管理,另一个区域由 "vmalloc" 管理;然后将内核的一部分更改为使用 "vmalloc" 而不是 "kmalloc",在这些地方很容易进行这些更改。
- My understanding is that When kmalloc() is used to allocate memory, It always comes from the 0 to 896MB within the RAM and not beyond that.
是;这是物理内存的第一个区域,适合 "kmalloc" 使用的内核 space 映射。
- When we use vmalloc() to allocate memory, Does that memory allocated anywhere from 896MB to 4GB range within the RAM ? or it is allocated only from 896MB upto 1GB range within RAM?
它将从不在第一个区域(“896MB 或更高”范围内的任何地方)的任何 RAM 中分配。
- When we say that kernel has only 1GB of virtual address space, Does that meant that the kernel can not access the RAM beyond 1GB ? If it can then how it is done ? Does the 128MB of kernel virtual address space are used for this purpose ?
内核的 1 GiB 虚拟 space;一些 (896MB) 将是物理地址 space 的线性映射,一些将是内存映射 (PCI) 设备,还有一些将预留为可以进行动态映射的区域。对于 "vmalloc" ,内核将分配 RAM 的物理页面,然后将它们映射到 "dynamic mapping area" (和 return 一个指向其映射位置的指针,与它的物理地址和中断无关"physical = virtual - base" 关系)。
注 1:确切的 sizes/limits 是可变的 - 例如内核可以编译为“2 GiB / 2 GiB 拆分”,其中内核 space 是 2 GiB(而不是“3 GiB / 1 GiB 拆分”); "kmalloc zone" 的大小可能取决于各种因素(space PCI 设备需要多少,有多少 RAM,等等)并且可能不是 896MB。
注 2:由于引入 "vmalloc" 来解决原始问题;计算机切换到 64 位(其中 "all memory" can/does 再次适合内核 space),并且 "vmalloc" 变得不必要(并且可能只是下降到 "kmalloc")。然而,发生了许多其他变化(NUMA、加密 RAM、非易失性 RAM 的引入,..;再加上任何人都无法追踪的更多安全漏洞),所以最初的设计缺陷已经达到了暂时的 "bad idea, but still technically not broken if we keep adding work-arounds for security vulnerabilities" 阶段(直到 RAM 和非易失性 RAM 大小不可避免地增加并且 "vmalloc" 在将来的某个时候再次需要 - 可能在大约 30 年内)。
考虑一个 32 位 x86 Linux 系统,具有 4 GB RAM 内存,因此如书中所述以及在许多论坛上,内存映射如下:
- 内核逻辑地址 - 高达 896 MB - 这是一对一映射的,可以使用 kmalloc 分配().
- 内核虚拟地址-128MB(896MB以上-内核逻辑地址)-使用vmalloc()[分配=41=] 并分配虚拟连续但物理上(分散在 RAM 内)非连续内存页。
有几点我不能完全理解并需要澄清。
我的理解是,当使用kmalloc()分配内存时,它总是来自RAM中的0到896MB,而不是超出。
当我们使用 vmalloc() 分配内存时,分配的内存是否在 RAM 中的 896MB 到 4GB 范围内?还是仅在 RAM 中从 896MB 到 1GB 范围分配?
当我们说内核只有1GB的虚拟地址时space,是否意味着内核不能访问超过1GB的RAM?如果可以那么它是如何完成的? 128MB的内核虚拟地址space是否用于此目的?
请帮忙。
理论上有3种不同"memory managers"。一个管理物理 RAM(主要跟踪空闲物理 RAM 的页面),一个管理虚拟 space(映射到每个虚拟地址 space 的内容,其中使用固定大小的块 - 页面大小),第三个管理 "heap"(允许将更大的虚拟地址 space 分成任意大小的部分)。
最初; Linux 内核试图使用它的内核 "heap" 来管理这三个截然不同的东西。通过将 "all RAM" 线性映射到内核 space,他们绕过了管理内核虚拟内存的需要,并最终在内核 space 中的虚拟地址和物理地址(例如 "physical = virtual - base"), 并且通过分配 "heap" 你也分配了物理内存。
这本来很好,因为当时计算机很少有超过 128 MiB 的 RAM(而且 Linus 没想到内核会存在很长时间,因为 GNU 正计划切换到 Hurd "soon" ),内核 space 明显大于 "all RAM"。随着 RAM 数量的增加,它变成了一个问题 -"all RAM" 变得比内核 space 大,所以 "use heap to manage 3 very different things" 无法工作。
当然,一旦它成为一个问题,很多内核的代码都依赖于 "kmalloc to allocate physical memory",这使得修复这个问题变得太难了。相反,他们将物理内存分成 2 个区域——一个区域由 "kmalloc" 管理,另一个区域由 "vmalloc" 管理;然后将内核的一部分更改为使用 "vmalloc" 而不是 "kmalloc",在这些地方很容易进行这些更改。
- My understanding is that When kmalloc() is used to allocate memory, It always comes from the 0 to 896MB within the RAM and not beyond that.
是;这是物理内存的第一个区域,适合 "kmalloc" 使用的内核 space 映射。
- When we use vmalloc() to allocate memory, Does that memory allocated anywhere from 896MB to 4GB range within the RAM ? or it is allocated only from 896MB upto 1GB range within RAM?
它将从不在第一个区域(“896MB 或更高”范围内的任何地方)的任何 RAM 中分配。
- When we say that kernel has only 1GB of virtual address space, Does that meant that the kernel can not access the RAM beyond 1GB ? If it can then how it is done ? Does the 128MB of kernel virtual address space are used for this purpose ?
内核的 1 GiB 虚拟 space;一些 (896MB) 将是物理地址 space 的线性映射,一些将是内存映射 (PCI) 设备,还有一些将预留为可以进行动态映射的区域。对于 "vmalloc" ,内核将分配 RAM 的物理页面,然后将它们映射到 "dynamic mapping area" (和 return 一个指向其映射位置的指针,与它的物理地址和中断无关"physical = virtual - base" 关系)。
注 1:确切的 sizes/limits 是可变的 - 例如内核可以编译为“2 GiB / 2 GiB 拆分”,其中内核 space 是 2 GiB(而不是“3 GiB / 1 GiB 拆分”); "kmalloc zone" 的大小可能取决于各种因素(space PCI 设备需要多少,有多少 RAM,等等)并且可能不是 896MB。
注 2:由于引入 "vmalloc" 来解决原始问题;计算机切换到 64 位(其中 "all memory" can/does 再次适合内核 space),并且 "vmalloc" 变得不必要(并且可能只是下降到 "kmalloc")。然而,发生了许多其他变化(NUMA、加密 RAM、非易失性 RAM 的引入,..;再加上任何人都无法追踪的更多安全漏洞),所以最初的设计缺陷已经达到了暂时的 "bad idea, but still technically not broken if we keep adding work-arounds for security vulnerabilities" 阶段(直到 RAM 和非易失性 RAM 大小不可避免地增加并且 "vmalloc" 在将来的某个时候再次需要 - 可能在大约 30 年内)。