内存的解剖结构如何映射核心空间

Ale*_*x44 7 c linux memory linux-kernel

我尝试了解Linux中将内核模式空间映射到用户模式空间的机制mmap.

首先,我有一个可加载的内核模块(LKM),它为字符设备提供了mmap-functionality.然后,用户空间应用程序打开设备并调用mmapLKM在内核模式空间(虚拟高地址)内的LKM堆上分配内存空间.在用户空间侧,数据指针指向虚拟低地址.

下图显示了我如何想象记忆的解剖结构.这是正确的吗?

内存映射

如果问题不明确,请告诉我,我会尝试添加更多细节.


编辑:图片是关于Gil Hamilton编辑的.黑色箭头现在指向物理地址.

小智 1

该图遗漏了一些重要的基本假设。

内核不需要mmap()访问用户空间内存。如果用户进程拥有内存,那么它已经根据定义映射到地址空间中。从这个意义上说,内存已经在用户和内核之间共享。

mmap()在用户的虚拟地址空间中创建一个新区域,以便以后访问时可以用物理内存填充该地址区域。内存的实际分配和页表项的修改是由内核完成的。

mmap()仅对管理用户一半的虚拟地址空间有意义。内核部分地址空间的管理方式完全不同。

此外,内核半部分由系统中的所有进程共享。每个进程都有其专用的虚拟地址空间,但页表的编程方式使得所有进程的内核部分的页表条目设置完全相同。

再次强调,内核并不是mmap()为了访问用户空间内存。mmap()而是内核向用户提供的一项服务,用于修改用户虚拟地址空间中的当前映射。

顺便说一句,如果内核愿意的话,实际上有几种方法可以访问用户内存。

首先,内核有一个专用的内核地址空间区域(作为其内核空间的一部分),它映射以连续方式存在的整个物理内存。(这在所有 64 位系统中都是如此。在 32 位系统中,内核必须即时“重新映射”才能实现这一点。)

其次,如果通过系统调用或异常(而不是通过硬件中断)进入内核,则拥有有效的进程上下文,因此内核可以直接“取消引用”用户空间指针来获取正确的值。

第三,如果内核想要在借用上下文(例如中断处理程序)中执行时遵循进程的用户空间指针,内核可以通过遍历树以获取vm_area_struct权限并遍历页表以找出实际的物理页来跟踪进程的虚拟地址框架。