为什么每次从内核模块读取CR3寄存器的内容会有所不同?

我正在编写一个内核驱动程序,目的是剖析Linux内核页表。 我发现,每当我读取CR3寄存器时,从驱动程序内部,CR3内容每次读取都不相同

为什么会发生? 当驱动程序以内核模式执行时,CR3需要指向内核页面目录(对吧?),那么为什么每次都改变CR3?

如果CR3不断变化,驱动程序的内存访问将如何正确发生?

正如其他人所提到的,您正在看到当前流程的“页面表”。 使用x86时,输入低于3的权限级别不会更改页表。 这就是为什么大多数操作系统为内核保留虚拟地址空间的部分。 该空间中的内存映射到每个进程。 内核地址空间中的内存可以通过将页面帧中的u / s标志设置为“0”来隐藏用户模式代码。 这将其标记为“系统”内存而不是用户内存。

通常在转换内核模式之后更改页表,这就是内核内存需要成为进程地址空间的一部分的原因。 它不知道在哪里可以找到它的数据结构。 一个例外是“系统管理模式”,它透明地切换地址空间。 但是,这只能在响应“系统管理中断”时出现,需要主板提供特殊的硬件支持,而且设计不能被操作系统压制或响应。

在保护模式下, 转换到内核模式之后 ,页表的操作总是由OS完成。 这是“模式切换”比完整上下文切换更快的原因之一。

CR3是页面目录指针。 每当地址空间发生变化时,它就会改变。 没有单个“内核”内存空间。 在大多数(所有?)内存模型中,您所看到的CR3值将与您所处的地址空间上下文相关(例如,您正在处理系统调用的进程等)。