我正在尝试学习一些关于 linux 内核和内存管理的知识。为此,我编写了一小段内核模块代码来转储 CR0 寄存器内容。我知道 CR0 中的第 31 位在设置时表示内核已打开分页但是,当我打印 CR0 时,我看到(对于我的特定实例)它被设置为 0x2。这表明(如果我理解正确的话)两个分页都被禁用并且处理器处于实模式(位 0 也未设置)。这让我感到惊讶,因为我期望保护模式/分页内存 - 不是所有多任务操作系统都这样做吗?内核可以运行在实模式/非分页和用户空间是保护模式/分页吗?有人可以解释为什么我可能会看到我在这里看到的吗?
请注意,我正在运行 2.6.18-274.el5 内核(64 位 RHEL 5 二进制文件)。
我的代码中有一个小错误,因此我打印的是随机垃圾而不是 CR0 寄存器。下面是工作代码 - 请注意,如果您在汇编中编码,则不需要调用 read_c0 函数...
.globl init_module
.globl cleanup_module
.text
init_module:
nop
movq $ENTER_MSG, %rdi
movq %cr3, %rsi
movq %rsi, %rdx
shrq $12, %rdx
movq %cr0, %r11
movq $FALSE, %rcx
andq PAGING_BIT_31, %r11
cmpq PAGING_BIT_31, %r11
jne .CONT1
movq $TRUE, %rcx
.CONT1:
movq $FALSE, %r8
movq %cr0, %r12
andq PROTMOD_BIT_0, %r12
cmpq PROTMOD_BIT_0, %r12
jne .CONT2
movq $TRUE, %r8
.CONT2:
movq %cr0, %r9
xorq %rax, %rax
callq printk
xorq %rax, %rax
retq
cleanup_module:
nop
movq $LEAVE_MSG, %rdi
movq %cr3, %rsi
xorq %rax, %rax
callq printk
retq
.section .rodata
ENTER_MSG:
.asciz "\n\nHELLO! CR3: %p, pCR3: %p \n\tPAGING IS %s\n\tPROTECTED MODE IS %s\n\tCR0: %p\n"
LEAVE_MSG:
.asciz "GOODBYE! CR3: %p\n"
PAGING_BIT_31:
.quad 0x80000000
PROTMOD_BIT_0:
.quad 0x1
FALSE:
.asciz "OFF"
TRUE:
.asciz "ON"