x86 linux cr3寄存器解除引用(如何才能访问页面目录?)

x86 linux cr3寄存器解除引用(如何才能访问页面目录?),linux,assembly,linux-kernel,x86-64,Linux,Assembly,Linux Kernel,X86 64,我正在学习/修补x86-64 linux上的内核内存管理。我想使用下面的asm代码查看cr3指向的页面目录的开头,但是取消引用cr3会导致内核锁定。访问cr3指向的内容的正确方式是什么?注意:我知道我需要在环0中,因此代码是一个小型内核模块(kmod.S): 并使用folling Makefile进行编译: obj-m += kmodule.o kmodule-objs := kmod.o all: make -C /lib/modules/$(shell uname -r)/buil

我正在学习/修补x86-64 linux上的内核内存管理。我想使用下面的asm代码查看cr3指向的页面目录的开头,但是取消引用cr3会导致内核锁定。访问cr3指向的内容的正确方式是什么?注意:我知道我需要在环0中,因此代码是一个小型内核模块(kmod.S):

并使用folling Makefile进行编译:

obj-m += kmodule.o
kmodule-objs := kmod.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

CR3寄存器的内容是针对CPU的,而不是针对内核的

软件总是使用虚拟地址。
如果要访问页表,应使用
中的帮助宏(尽管有些过时)。

%cr3
包含物理地址。有关如何“使其可见”的信息,请参见。您需要创建一个临时映射。即使内核也不能使用物理地址?如果我正在编写自己的操作系统,在某个时候我不需要物理地址吗?感谢FrankF.Adel Qodmani,我编辑了原始问题,添加了我使用的makefile。@boneheadgeek否内核没有被阻止使用物理地址;只是,使用物理地址的唯一方法是。。。创建映射到它的虚拟地址。x86 CPU中没有允许“直接加载/存储到/从物理地址”的机制。因此。。。如上所述,请阅读另一篇关于如何访问此内存的帖子。@boneheadgeek为了澄清,有一种直接使用物理地址的方法,那就是禁用MMU(清除
%cr0
中的第31位)。这样做,即使是暂时的,在Linux中也永远不会安全,除非是非常特定的代码路径,因为如果在MMU关闭的窗口中发生任何中断和/或IPI,都会崩溃。所以,为了学究的缘故。。。你可以做到,但正确的做法是。。。创建一个临时映射。谢谢@CL。这和FrankH的回复一起帮助我找到了如何得到我想要的。事实证明,(在内核模式下)向CR3的物理地址添加PAGE_偏移量就足够了,以便访问相关的PAGE表。我想投票,但分数还不够。谢谢@CL.我相信CR3的内容是“为CPU准备的”,这意味着它是供硬件页表遍历器(MMU)使用的,对吗?因此,在我看来,必须有其他一些机制来确保包含页面目录(PGD)的物理页面不会被交换到磁盘。这是怎么回事?如果内核只是选择为运行队列中的所有进程锁定包含PGD的所有页面,那么它将消耗大量RAM。那么它是如何做到的呢?你能给我举一个像Linux/Windows/*BSD这样的商品操作系统的例子吗?交换和调度是由操作系统完成的,而不是由CPU完成的。要提问,请使用“提问”按钮。
obj-m += kmodule.o
kmodule-objs := kmod.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean