lll*_*lll 1 linux memory memory-layout linux-kernel windows-kernel
似乎在Windows 32位上,内核将从完全4G用户虚拟内存空间中保留1G虚拟内存,并将一些内核空间映射到此1G空间.
所以我的问题是:
我认为
cat /proc/pid/map
Run Code Online (Sandbox Code Playgroud)
只能看到某些进程的用户空间布局..
谢谢!
实际上,在 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 的当前进程虚拟地址空间。地图应该是三维的,因为有 4MB 区域由具有 1024 个条目(页面)的页表描述,并且并非所有页面都可能存在,但为了保持地图清晰,练习要求用户折叠这些区域,显示描述当前页面的第一个页面条目的内容,希望该页表中的所有后续页面共享相同的属性(实际上可能是也可能不是)。
该映射与内核 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
Run Code Online (Sandbox Code Playgroud)
你可以看到有3GB的巨大内存空间,在本例中几乎是空的(该进程只是一个小的C应用程序,并且使用了不到4MB,全部包含在页表中,其第一个存在的页面是只读页面,假设是程序代码的一部分,或者可能是静态字符串)。
在3GB边界附近有两个小区域可读写,它们可能属于用户程序加载的共享库。
最后 4 行(256 个目录条目)几乎全部属于内核。实际存在和使用的条目有 224 个。这些映射了前 896MB 物理内存,它是内核所在的空间。在 RAM 超过 896MB 的系统中,内核使用最后 32 个条目来访问超过 896MB 标记的物理内存。
在32位Linux上是否有类似的情况?
是.在32位Linux上,默认情况下,内核保留地址空间的高四分之一(从C0000000到内存顶部的1G)供自己使用.
如果是这样,我们怎样才能看到整个内存布局?
你不能./proc/pid/maps仅显示用户空间中存在的映射.用户空间应用程序无法访问内核内存,因此未显示.
请记住使用这种安排的原因 - 当内核处于活动状态时,它需要能够安装自己的映射,同时仍然保持用户空间映射处于活动状态(例如,它可以将数据从用户空间复制到用户空间).它通过为自己保留高内存范围来实现这一点.
内核中内存映射的位置与内核本身之外的任何内容都无关,因此除了意外或某些调试消息之外,它根本不会暴露给用户空间.