gpt4 book ai didi

c - Linux 内核中的内存映射 - vamlloc() 和 kmalloc() 的使用

转载 作者:行者123 更新时间:2023-11-30 14:34:47 24 4
gpt4 key购买 nike

考虑到具有 4 GB RAM 内存的 32 位 x86 Linux 系统,因此正如书籍和许多论坛中所述,内存映射如下:

  1. 内核逻辑地址 - 最大896 MB - 一对一映射,可以使用kmalloc()分配。
  2. 内核虚拟地址 - 128MB(896MB以上 - 内核逻辑地址) - 使用vmalloc()分配,并分配虚拟连续但物理上的(分散在RAM中)非连续的内存页面。

有几点我无法完全理解并需要澄清。

  1. 我的理解是,当使用kmalloc()分配内存时,它总是来自RAM内的0到896MB,而不是超出这个范围。

  2. 当我们使用vmalloc()分配内存时,分配的内存是否在RAM内的896MB到4GB范围内?还是只在 RAM 内分配 896MB 到 1GB 范围?

  3. 当我们说内核只有 1GB 的虚拟地址空间时,是否意味着内核无法访问超过 1GB 的 RAM?如果可以那么它是如何做到的? 128MB 内核虚拟地址空间是否用于此目的?

请帮忙。

最佳答案

理论上有 3 种不同的“内存管理器”。一个管理物理 RAM(主要跟踪空闲物理 RAM 的页面),一个管理虚拟空间(映射到每个虚拟地址空间的内容,使用固定大小的 block - 页面大小),第三个管理“堆”(允许将更大的虚拟地址空间分割成任意大小的 block )。

原来; Linux 内核尝试使用其内核“堆”来管理所有这 3 个截然不同的事物。通过将“所有 RAM”线性映射到内核空间,它们绕过了管理内核虚拟内存的需要,最终得到了内核空间中的虚拟地址和物理地址之间的简单关系(例如“物理 = 虚拟 - 基址”),并通过分配“堆”还分配物理内存。

这本来很好,因为当时计算机很少有超过 128 MiB 的 RAM(Linus 并不期望内核存在很长时间,因为 GNU 计划“很快”切换到 Hurd),并且内核空间明显大于“所有 RAM”。随着 RAM 量的增加,它变成了一个问题 -“所有 RAM”变得大于内核空间,因此“使用堆来管理 3 个截然不同的事物”无法工作。

当然,一旦出现问题,很多内核代码都依赖于“kmalloc来分配物理内存”,这使得解决问题变得非常困难。相反,他们将物理内存分为 2 个区域 - 一个区域由“kmalloc”管理,另一个区域由“vmalloc”管理;然后更改内核部分以使用“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”使用的内核空间映射。

  1. 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?

它将从不在第一个区域的任何 RAM(“896MB 或更高”范围内的任何位置)分配。

  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 ? If it can then how it is done ? Does the 128MB of kernel virtual address space are used for this purpose ?

内核的 1 GiB 虚拟空间;一些(896MB)将是物理地址空间的线性映射,一些将是内存映射(PCI)设备,还有一些将留出作为可以进行动态映射的区域。对于“vmalloc”,内核将分配 RAM 的物理页,然后将它们映射到“动态映射区域”(并返回一个指向其映射位置的指针,该指针与其物理地址无关,并打破了“物理 = 虚拟 -基础”关系)。

注 1:确切的尺寸/限制是可变的 - 例如内核可以编译为“2 GiB/2 GiB split”,其中内核空间为 2 GiB(而不是“3 GiB/1 GiB split”); “kmalloc 区域”的大小可能取决于各种因素(PCI 设备需要多少空间、有多少 RAM 等),并且可能不是 896MB。

注2:自从引入“vmalloc”来解决原来的问题;计算机切换到 64 位(其中“所有内存”可以/确实再次适合内核空间),并且“vmalloc”变得不必要(并且可能只是落入“kmalloc”)。然而,还发生了许多其他变化(引入 NUMA、加密 RAM、非 volatile RAM,……;再加上任何一个人都无法跟踪的安全漏洞),因此最初的设计缺陷已经达到了暂时的“坏主意,但如果我们继续添加安全漏洞的解决方法,技术上仍然没有被破坏”阶段(直到 RAM 和非 volatile RAM 大小不可避免地增加,并且在未来某个时候再次需要“vmalloc” - 可能在大约 30 年)。

关于c - Linux 内核中的内存映射 - vamlloc() 和 kmalloc() 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58837677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com