Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为什么每次从内核模块读取时,CR3寄存器内容都会发生变化?_Linux_Linux Kernel_X86_Linux Device Driver_X86 64 - Fatal编程技术网

Linux 为什么每次从内核模块读取时,CR3寄存器内容都会发生变化?

Linux 为什么每次从内核模块读取时,CR3寄存器内容都会发生变化?,linux,linux-kernel,x86,linux-device-driver,x86-64,Linux,Linux Kernel,X86,Linux Device Driver,X86 64,我正在编写一个内核驱动程序,目的是剖析Linux内核页表。 我发现,每当我从驱动程序内部读取CR3寄存器时,CR3的内容每次读取时都会发生变化 为什么会发生这种情况?由于驱动程序在内核模式下执行,CR3需要指向内核页面目录(对吗?),那么为什么CR3每次都在更改 如果CR3不断更改,驱动程序如何按预期正确访问内存?CR3是页面目录指针。它至少会在地址空间每次更改时更改。没有单一的“内核”内存空间。在大多数(所有?)内存模型中,您看到的CR3值将特定于您所处的地址空间上下文(例如,您正在处理来自哪

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

为什么会发生这种情况?由于驱动程序在内核模式下执行,CR3需要指向内核页面目录(对吗?),那么为什么CR3每次都在更改


如果CR3不断更改,驱动程序如何按预期正确访问内存?

CR3是页面目录指针。它至少会在地址空间每次更改时更改。没有单一的“内核”内存空间。在大多数(所有?)内存模型中,您看到的CR3值将特定于您所处的地址空间上下文(例如,您正在处理来自哪个进程的系统调用等)。

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

更改页表通常在转换内核模式后完成,这就是为什么内核内存需要成为进程地址空间的一部分。否则它不知道在哪里可以找到它的数据结构。一个例外是“系统管理模式”,它透明地切换地址空间。然而,这只能在响应“系统管理中断”时发生,需要来自主板的特殊硬件支持,并且从设计上来说,操作系统无法抑制或响应


否则,在保护模式下,页面表的操作总是在转换到内核模式后由操作系统完成。这就是为什么“模式切换”比完整上下文切换快的部分原因。

假设我为内核模块声明了一个全局字符数组。现在,如果CR3不指向内核空间目录,而是指向其他位置,那么访问该阵列将如何成功?访问确实成功!!为什么访问不成功?使用不同的顶级页面目录并不意味着它不能为变量指向相同的物理地址。您确定这就是发生的情况吗?因为这意味着每个进程的分页结构都必须包含所有这些内核数据的映射!这似乎不是个好主意。这也会限制进程可以使用的地址范围。我几乎可以肯定这就是正在发生的情况(请注意,较低级别的页表可以共享)。你已经准备好了装备,追踪它,自己去发现。这不是重点吗?访问成功是因为内核模式地址空间对每个进程的映射方式相同。每个进程的用户模式地址空间都必须改变,这意味着CR3将根据正在运行的进程而改变。从我读到的内容来看,CR3的内容将是最后一个“正在运行”进程的CR3(linux使用每个进程的分页结构)。所以我想分析这种变化没有多大意义。