简体   繁体   English

Memory Linux Kernel 中的映射 - 使用 vamlloc() 和 kmalloc()

[英]Memory Mapping in Linux Kernel - use of vamlloc() and kmalloc()

Considering a 32bit x86 Linux system with 4 GB of RAM memory, So as described in books as well as on many forums that the Memory mapping would be as follows: Considering a 32bit x86 Linux system with 4 GB of RAM memory, So as described in books as well as on many forums that the Memory mapping would be as follows:

  1. Kernel logical address - upto 896 MB - Which is one to one mapped and can be allocated using kmalloc() . Kernel 逻辑地址- 最多896 MB - 一对一映射,可以使用kmalloc()分配。
  2. Kernel virtual address - 128MB (above 896MB - kernel logical address) - allocated using vmalloc() and allocates Virtually contiguous but physically(scattered within RAM ) non-contiguous memory pages. Kernel 虚拟地址- 128MB (896MB 以上 - kernel 逻辑地址) - 使用vmalloc()分配并分配虚拟连续但物理上(分散在RAM内)非连续 kernel 页面

Few points that I am not able to fully understand and need clarity on.我无法完全理解并需要澄清的几点。

  1. 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()分配memory 时,它总是来自RAM 中的0 到896MB,而不是超出这个范围。

  2. When we use vmalloc() to allocate memory, Does that memory allocated anywhere from 896MB to 4GB range within the RAM?当我们使用vmalloc()分配 memory 时,memory 是否在 RAM 中分配了 896MB 到 4GB 范围内的任何地方? or it is allocated only from 896MB upto 1GB range within RAM?还是仅在 RAM 内从 896MB 到 1GB 范围内分配?

  3. 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?当我们说 kernel 只有 1GB 的虚拟地址空间时,那是否意味着 kernel 无法访问超过 1GB 的 RAM? If it can then how it is done?如果可以,那么它是如何完成的? Does the 128MB of kernel virtual address space are used for this purpose? kernel 的 128MB 虚拟地址空间是否用于此目的?

Please help.请帮忙。

In theory there are 3 different "memory managers".理论上有 3 种不同的“内存管理器”。 One manages physical RAM (mostly keeping track of pages of free physical RAM), one manages virtual space (what is mapped into each virtual address space where, working with fixed size pieces - the page size), and the third manages "heap" (allowing a larger area of the virtual address space to be split up into arbitrary sized pieces).一个管理物理 RAM(主要跟踪空闲物理 RAM 的页面),一个管理虚拟空间(映射到每个虚拟地址空间的内容,使用固定大小的片段 - 页面大小),第三个管理“堆”(允许将更大区域的虚拟地址空间分成任意大小的块)。

Originally;起初; the Linux kernel tried to use its kernel "heap" to manage all 3 of these very different things. Linux kernel 试图使用它的 kernel “堆”来管理所有这三个非常不同的东西。 By linearly mapping "all RAM" into kernel space they bypass the need for managing the kernel's virtual memory and end up with a simple relationship between virtual addresses in kernel space and physical addresses (eg "physical = virtual - base"), and by allocating "heap" you also allocate physical memory.通过将“所有 RAM”线性映射到 kernel 空间,它们绕过了管理内核虚拟 memory 的需要,最终在 kernel 空间中的虚拟地址和物理地址之间建立了简单的关系“堆”您还分配物理 memory。

This was fine originally because at the time computers rarely had more than 128 MiB of RAM (and Linus didn't expect the kernel to exist for very long, as GNU were planning to switch to Hurd "soon"), and kernel space was significantly larger than "all RAM".最初这很好,因为当时计算机很少有超过 128 MiB 的 RAM(Linus 并不期望 kernel 存在很长时间,因为 GNU 计划“很快”切换到 Hurd),并且 kernel 空间显着大于“所有 RAM”。 As the amount of RAM increased it became a problem -"all RAM" became larger than kernel space, so "use heap to manage 3 very different things" couldn't work.随着 RAM 数量的增加,它变成了一个问题——“所有 RAM”变得比 kernel 空间大,所以“使用堆来管理 3 个非常不同的东西”是行不通的。

Of course once it became a problem a lot of the kernel's code dependent on "kmalloc to allocate physical memory", making it too hard to fix the problem.当然,一旦出现问题,很多内核代码都依赖于“kmalloc 分配物理内存”,因此很难解决问题。 Instead, they split physical memory into 2 zones - one zone that would be managed by "kmalloc" and another zone that is managed by "vmalloc";相反,他们将物理 memory 拆分为 2 个区域 - 一个由“kmalloc”管理的区域和另一个由“vmalloc”管理的区域; then changed pieces of the kernel to use "vmalloc" instead of "kmalloc" where it's easy make those changes.然后更改 kernel 的部分以使用“vmalloc”而不是“kmalloc”,这样很容易进行这些更改。

  1. 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() 分配memory 时,它总是来自RAM 中的0 到896MB,而不是超出这个范围。

Yes;是的; this is the first zone of physical memory, which fits into the kernel space mapping that "kmalloc" uses.这是物理 memory 的第一个区域,它适合“kmalloc”使用的 kernel 空间映射。

  1. When we use vmalloc() to allocate memory, Does that memory allocated anywhere from 896MB to 4GB range within the RAM?当我们使用 vmalloc() 分配 memory 时,memory 是否在 RAM 中分配了 896MB 到 4GB 范围内的任何地方? or it is allocated only from 896MB upto 1GB range within RAM?还是仅在 RAM 内从 896MB 到 1GB 范围内分配?

It would be allocated from any RAM that is not in the first zone (anywhere in "896MB or higher" range).它将从不在第一个区域(“896MB 或更高”范围内的任何位置)中的任何 RAM 分配。

  1. 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?当我们说 kernel 只有 1GB 的虚拟地址空间时,那是否意味着 kernel 无法访问超过 1GB 的 RAM? If it can then how it is done?如果可以,那么它是如何完成的? Does the 128MB of kernel virtual address space are used for this purpose? kernel 的 128MB 虚拟地址空间是否用于此目的?

Of the kernel's 1 GiB of virtual space;内核的 1 GiB 虚拟空间; some (896MB) will be the linear mapping of the physical address space, some will be memory mapped (PCI) devices, and some will be set aside as an area where dynamic mappings can be made.一些 (896MB) 将是物理地址空间的线性映射,一些将是 memory 映射 (PCI) 设备,还有一些将被留作可以进行动态映射的区域。 For "vmalloc" the kernel would allocate physical pages of RAM and then map them into the "dynamic mapping area" (and return a pointer to where it was mapped that has nothing to do with its physical address and breaks the "physical = virtual - base" relationship).对于“vmalloc”,kernel 将分配 RAM 的物理页面,然后将 map 分配到“动态映射区域”(并返回一个指向与其物理地址无关的映射位置的指针,并打破“物理 = 虚拟 -基”关系)。

Note 1: Exact sizes/limits are variable - eg kernel can be compiled for "2 GiB / 2 GiB split" where kernel space is 2 GiB (instead of "3 GiB / 1 GiB split");注 1:确切的大小/限制是可变的 - 例如 kernel 可以编译为“2 GiB / 2 GiB 拆分”,其中 kernel 空间为 2 GiB(而不是“3 GiB / 1 GiB 拆分”); and the size of the "kmalloc zone" probably depends on various factors (how much space PCI devices need, how much RAM there is, etc) and may be something other than 896MB.并且“kmalloc 区域”的大小可能取决于各种因素(PCI 设备需要多少空间、有多少 RAM 等),并且可能不是 896MB。

Note 2: Since introducing "vmalloc" to work around the original problem;注2:由于引入了“vmalloc”来解决原来的问题; computers switched to 64 bit (where "all memory" can/does fit in kernel space again), and "vmalloc" became unnecessary (and probably just falls through to "kmalloc").计算机切换到 64 位(其中“所有内存”可以/确实适合 kernel 空间),并且“vmalloc”变得不必要(并且可能只是落入“kmalloc”)。 However a lot of other changes have occurred (introduction of NUMA, encrypted RAM, non-volatile RAM, ..; plus more security vulnerabilities than any single person can keep track of) so the original design flaw has reached a temporary "bad idea, but still technically not broken if we keep adding work-arounds for security vulnerabilities" stage (until RAM and non-volatile RAM sizes inevitably increase and "vmalloc" becomes needed again at some point in the future - probably in about 30 years).然而,许多其他变化已经发生(NUMA 的引入、加密 RAM、非易失性 RAM ......;加上任何一个人都无法追踪的更多安全漏洞),因此最初的设计缺陷已经达到了暂时的“坏主意,但如果我们继续为安全漏洞添加变通方法,技术上仍然不会损坏”阶段(直到 RAM 和非易失性 RAM 的大小不可避免地增加,并且在未来的某个时候再次需要“vmalloc” - 可能在大约 30 年内)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM