【发布时间】:2013-07-30 18:59:58
【问题描述】:
我正在学习/修改 x86-64 linux 上的内核内存管理。我想使用下面的 asm 代码查看 cr3 指向的页面目录的开头,但取消引用 cr3 会导致内核锁定。访问 cr3 指向的正确方法是什么?注意我知道我需要在环 0 中,因此代码是一个小内核模块 (kmod.S):
.globl init_module
.globl cleanup_module
.text
init_module:
nop
movq $ENTER_MSG, %rdi
movq %cr3, %rsi
movq (%rsi), %rdx
xorq %rax, %rax
callq printk
xorq %rax, %rax
retq
cleanup_module:
nop
movq $LEAVE_MSG, %rdi
xorq %rax, %rax
callq printk
retq
.section .rodata
ENTER_MSG:
.asciz "\n\nHELLO! CR3: %p, (CR3): %p\n"
LEAVE_MSG:
.asciz "GOODBYE!\n\n"
并使用以下 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包含一个物理地址。请参阅stackoverflow.com/questions/11621911/… 了解如何“使其可见”。您需要创建一个临时映射。 -
甚至禁止内核使用物理地址?如果我正在编写自己的操作系统,在某些时候我不需要物理地址怎么办?谢谢弗兰克F。
-
Adel Qodmani,我编辑了原始问题以添加我使用的 makefile。
-
@boneheadgeek 不,内核未被阻止使用物理地址;只是,使用物理地址的唯一方法是……创建一个映射到它的虚拟地址。 x86 CPU 中没有允许“直接加载/存储到/从物理地址”的机制。因此...如前所述,请阅读有关如何访问此内存的其他帖子。
-
@boneheadgeek 澄清一下,有一种方法可以直接使用物理地址,那就是禁用 MMU(清除
%cr0中的第 31 位)。这样做,即使是暂时的,在 Linux 中永远不安全,除非是非常特定的代码路径,因为如果在 MMU 关闭的窗口期间发生任何中断和/或 IPI 都会崩溃。所以,为了迂腐……你可以这样做,但正确的做法是……创建一个临时映射。
标签: linux assembly linux-kernel x86-64