内核虚拟地址和内核逻辑地址之间的区别?

时间:2012-01-03 05:56:19

标签: linux-kernel linux-device-driver

我无法区分内核逻辑地址和虚拟地址。在Linux设备驱动程序书中它说所有逻辑地址都是内核虚拟地址,而虚拟地址没有任何线性映射。但是,当我们说这是合乎逻辑的,当我们说虚拟和在哪种情况下我们使用这两个时,逻辑上是明智的吗?

4 个答案:

答案 0 :(得分:28)

Linux内核映射属于内核的大部分虚拟地址空间,以使用物理内存的第一部分的偏移执行1:1映射。 (对于32位x86,1Gb略小,对于其他处理器或配置可能会有所不同)。例如,对于x86上的内核代码,地址0xc00000001被映射到物理地址0x1。

这称为逻辑映射 - 1:1映射(带偏移量),允许内核访问机器的大部分物理内存。

但这还不够 - 有时候我们在32位机器上有超过1Gb的物理内存,有时我们想引用非连续的物理内存块作为连续的事情来简化,有时我们想要映射内存映射的IO区域不是RAM。

为此,内核将一个区域保留在其虚拟地址空间的顶部,在该区域中,它执行“随机”页面到页面映射。那里的映射不遵循逻辑映射区域的1:1模式。这就是我们所说的虚拟映射。

在许多平台上添加它是很重要的(x86是一个例子),逻辑映射和虚拟映射都是使用相同的硬件机制(TLB控制虚拟内存)完成的。在许多情况下,“逻辑映射”实际上是使用处理器的虚拟内存工具完成的,因此这可能有点令人困惑。因此,差异是映射完成的模式:逻辑1:1,虚拟随机。

答案 1 :(得分:17)

基本上有3种寻址,即

  1. 逻辑寻址:地址由基数和偏移量组成。这只是分段寻址,其中程序中的地址(或偏移量)始终与段描述符中的基值一起使用
  2. 线性寻址:也称为虚拟地址。这里的地址是连续的,但实际地址不是。分页用于实现此目的。
  3. 物理寻址:主存储器上的实际地址!
  4. 现在,在linux中,内核内存(在地址空间中)超过3 GB(3GB到4GB),即0xc000000 ......内核使用的地址不是物理地址。要映射虚拟地址,请使用PAGE_OFFSET。必须注意不涉及页面翻译。即这些地址本质上是连续的。但是这是有限的,即x86上的896 MB。除了哪个分页用于翻译。使用vmalloc时,将返回这些地址以访问分配的内存。

    简而言之,当有人在用户空间的上下文中引用虚拟内存时,那就是通过分页。如果提到内核虚拟内存,那么它是PAGE_OFFSETed或vmalloced地址。

    (参考 - 了解Linux内核 - 基于2.6)

    词shash

答案 2 :(得分:9)

内核逻辑地址是通过普通CPU内存访问功能可访问内核代码的映射。在32位系统上,只有4GB的内核逻辑地址空间存在,即使使用的物理内存多于该内存。物理内存支持的逻辑地址空间可以使用kmalloc分配。

虚拟地址不一定具有相应的逻辑地址。您可以使用vmalloc分配物理内存并获取没有相应逻辑地址的虚拟地址(例如,在具有PAE的32位系统上)。然后,您可以使用kmap为该虚拟地址分配逻辑地址。

答案 3 :(得分:1)

简单来说,虚拟地址将包含“高内存”,如果您的RAM大小超过内核的地址范围(通常为1G / 3G),则不会对物理地址执行1:1映射X86,你的RAM是3G但你的内核寻址范围是1G)以及从kmap()和vmalloc()返回的地址,这需要内核为内存映射建立页表。由于逻辑地址始终由内核映射(1:1映射),因此您无需显式调用内核API,例如set_pte来设置特定页面的页表项。

所以虚拟地址不能一直是逻辑地址。