app*_*eev 5 linux x86 x86-64 linux-device-driver linux-kernel
我正在编写一个内核驱动程序,目的是剖析 Linux 内核页表。我发现,每当我从驱动程序内部读取 CR3 寄存器时,每次读取 CR3 的内容都会有所不同!
为什么会发生这种情况?既然驱动在内核态执行,CR3需要指向内核页目录(对吧?),那为什么CR3每次都在变化呢?
如果 CR3 不断变化,驱动程序如何按预期正确进行内存访问?
正如其他人提到的,您正在看到当前进程的“页表”。对于 x86,输入低于 3 的权限级别不会更改页表。这就是大多数操作系统为内核保留部分虚拟地址空间的原因。该空间中的内存被映射到每个进程。通过将页帧中的 u/s 标志设置为“0”,可以对用户模式代码隐藏内核地址空间中的内存。这将其标记为“系统”内存而不是用户内存。
更改页表通常是在转换内核模式后完成的,这就是为什么内核内存需要成为进程地址空间的一部分。否则它不知道在哪里可以找到它的数据结构。一个例外是“系统管理模式”,它透明地切换地址空间。然而,这只能在响应“系统管理中断”时发生,需要主板的特殊硬件支持,并且在设计上不能被操作系统抑制或响应。
否则,在保护模式下,页表的操作始终由操作系统在转换为内核模式后完成。这就是“模式切换”比完整上下文切换更快的部分原因。