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

Linux kernel 内核虚拟地址和内核逻辑地址之间的区别?,linux-kernel,linux-device-driver,Linux Kernel,Linux Device Driver,我无法准确区分内核逻辑地址和虚拟地址。在Linux设备驱动程序手册中,它说所有的逻辑地址都是内核虚拟地址,而虚拟地址并没有任何线性映射。但是从逻辑上讲,当我们说它是逻辑的,当我们说它是虚拟的,在什么情况下我们使用这两个?内核逻辑地址是可以通过正常的CPU内存访问函数访问内核代码的映射。在32位系统上,只有4GB的内核逻辑地址空间存在,即使使用的物理内存超过4GB。物理内存支持的逻辑地址空间可以使用kmalloc进行分配 虚拟地址不一定有相应的逻辑地址。您可以使用vmalloc分配物理内存,并返回

我无法准确区分内核逻辑地址和虚拟地址。在Linux设备驱动程序手册中,它说所有的逻辑地址都是内核虚拟地址,而虚拟地址并没有任何线性映射。但是从逻辑上讲,当我们说它是逻辑的,当我们说它是虚拟的,在什么情况下我们使用这两个?

内核逻辑地址是可以通过正常的CPU内存访问函数访问内核代码的映射。在32位系统上,只有4GB的内核逻辑地址空间存在,即使使用的物理内存超过4GB。物理内存支持的逻辑地址空间可以使用
kmalloc
进行分配


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

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

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

但这还不够——有时我们在32位机器上有超过1Gb的物理内存,有时我们希望将非连续的物理内存块引用为连续的以使事情变得简单,有时我们希望映射非RAM的内存映射IO区域

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


必须补充的是,在许多平台上(x86就是一个例子),逻辑和虚拟映射都是使用相同的硬件机制(TLB控制虚拟内存)完成的。在许多情况下,“逻辑映射”实际上是使用处理器的虚拟内存设施来完成的,因此这可能会有点混乱。因此,不同之处在于映射所依据的模式:逻辑为1:1,虚拟为随机。

基本上有3种寻址,即

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

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

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


    Shash

    简单地说,虚拟地址将包括“高内存”,它不会对物理地址进行1:1映射,如果您的RAM大小超过内核的地址范围(通常,对于X86中的1G/3G,您的RAM是3G,但内核寻址范围是1G),并且还包括从kmap()和vmalloc()返回的地址,这需要内核为内存映射建立页表。由于逻辑地址总是由内核进行内存映射(1:1映射),因此不需要显式调用内核API,如set_pte为特定页面设置页面表条目

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