当前位置: 首页 > 面试题库 >

在Linux x86上,内核空间是否映射到用户空间?

司寇望
2023-03-14
问题内容

似乎在Windows 32位上,内核将从全部4G用户虚拟内存空间中保留1G虚拟内存,并将 某些 内核空间映射到此1G空间中。

所以我的问题是:

  1. 在32位Linux上是否有类似情况?
  2. 如果是这样,我们如何看到整个内存布局?

我认为

cat /proc/pid/map

只能看到某些过程的用户空间布局。

谢谢!


问题答案:

实际上,在32位Windows上,如果没有/3G引导选项,内核将映射到线性地址空间的前2GB,剩下2GB的空间供用户处理。

Linux做类似的事情,但是它在最高1GB的线性空间中映射内核,因此为用户进程留出了3GB的空间。

我不知道您是否可以仅使用/
proc文件系统来查看整个内存布局。在为学生设计的实验室中,我创建了一个微型设备驱动程序,该驱动程序使用户可以查看物理内存地址,并获取几个控制寄存器的内容,例如CR3(目录页面基址)。

通过使用这两种操作,一个人可以浏览当前进程的目录页面(一个正在执行此操作),并查看存在的页面,哪些页面由用户和内核拥有,或者仅由内核拥有,使用该信息,它们必须显示一个映射,显示内存使用情况,包括内核空间。

看看这个PDF。这是我们在课程中所做的所有实验的编译版本。
http://www.atc.us.es/asignaturas/tpbn/PracticasTPBN2011.pdf

在PDF的第36页(文档的第30页)中,您将看到内存映射的外观。这是来自练习3的练习3.2的结果。

文字是西班牙文,但是如果您无法理解某些内容,可以确定可以使用翻译器或类似的工具。本实验假定学生已阅读有关分页系统如何工作以及如何解释目录和页面条目的布局的信息。

地图是这样的。16x64块。块中的每个单元代表4MB的当前进程虚拟地址空间。地图应该是三维的,因为页面表用1024个条目(页面)描述了4MB区域,并且可能不会显示所有页面,但是为了保持地图清晰,练习要求用户折叠这些区域,显示了描述当前页面的第一个页面条目的内容,希望该页面表中的所有后续页面都共享相同的属性(实际上可能正确也可能不正确)。

该映射与内核2.6.X一起使用。其中PAE不使用和PSE使用(PAE并且PSE是控制寄存器中的两个位字段CR4)。PAE启用2MB页面并PSE启用4MB页面。4KB页面始终可用。

. : PDE not present, or page table empty.
X : 4MB page, supervisor.
R : 4MB page, user, read only.
* : 4MB page, user, read/write.
x : Page table with at least one entry describing a supervisor page.
r : Page table with at least one entry describing an user page, read only.
+ : Page table with at least one entry describing an user page, read/write.

................................r...............................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
...............................+..............................+.
xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..x...........................xx

您可以看到有3GB的巨大内存空间,在这种情况下,该空间几乎是空的(该过程只是一个小的C应用程序,并且使用了不到4MB的内存,所有这些都包含在一个页表中,该页的第一个当前页是只读页)
,假定是程序代码的一部分,或者可能是静态字符串)。

在3GB边界附近有两个读/写小区域,它们可能属于用户程序加载的共享库。

后4行(256个目录条目)几乎全部属于内核。实际存在和使用了224个条目。这些映射了前896MB的物理内存,它是内核所在的空间。在RAM超过896MB的系统中,内核使用最后32个条目访问超出896MB标记的物理内存。



 类似资料:
  • 问题内容: 假设使用基于页面的方案分配缓冲区。一种实现mmap的方法是使用remap_pfn_range,但LDD3表示这不适用于常规内存。看来我们可以通过使用SetPageReserved标记保留的页面来解决此问题,以便将其锁定在内存中。但是,不是所有内核内存都已经不可交换,即已经保留了吗?为什么需要显式设置保留位? 这与从HIGH_MEM分配的页面有关吗? 问题答案: 使用mmap方法从内核映

  • 问题内容: 我在Linux中编写了一个自定义设备驱动程序,该驱动程序必须能够非常快速地响应中断。用户空间实现中已经存在处理此问题的代码,但是它太慢了,因为它依赖于软件不断检查中断线的状态。经过研究,我发现您可以从内核模块注册这些中断线,并执行由函数指针提供的功能。但是我们要执行的代码是在用户空间中,是否有一种方法可以从内核空间模块调用用户空间中的函数? 问题答案: 从内核调用用户空间功能很不走运,

  • 问题内容: 我知道udev在linux系统上运行,并且它通过netlink套接字接收从内核发送的uevent。 但是,我的问题是: 内核如何发出事件?它必须是通过添加/删除设备触发的,然后将事件发送给udev。内核如何做到这一点?(是否可以找到任何代码示例?) udev仅通过netlink套接字接收这些uevent。这是udev做到这一点的唯一方法。它是否正确? 当uevent从内核发出时,我知道

  • 问题内容: 我正在尝试打电话 直接,但获得EFAULT错误代码。出现此错误是因为 buf 指向内核空间中的内存。 那么,是否有可能从内核分配用户空间内存? 与 内核内存相似并返回指向内核内存的指针。 问题答案: 您可以使用以下方法临时禁用内存地址有效性检查:

  • 问题内容: 内核堆栈和用户堆栈有什么区别?为什么要使用内核堆栈?如果在ISR中声明了局部变量,它将存储在哪里?每个进程都有自己的内核堆栈吗?那么,进程如何在这两个堆栈之间进行协调? 问题答案: 内核堆栈和用户堆栈有什么区别? 简而言之,除了在内存中使用不同的位置(并因此为堆栈指针寄存器使用不同的值)之外,什么也没有,而且通常使用不同的内存访问保护。也就是说,在用户模式下执行时,即使映射了内核内存(

  • 问题内容: 这是一个要阐述的问题:为什么说内核在进程地址空间中? 这可能是一个愚蠢的问题,但在我脑海中浮现出来。有关进程地址空间和虚拟内存布局的所有文字都提到进程地址空间具有为内核保留的空间。例如,在32位系统上,进程地址空间为4GB,其中1 GB为Linux中的内核保留(其他OS上可能有所不同)。 我只是想知道为什么当进程无法直接寻址内核时,为什么说内核位于进程地址空间中。为什么我们不说内核具有