CR0 控制位解释
主要控制位详解
1. 保护模式使能位
#define CR0_PE (1UL << 0) // 位0 - Protection Enable
作用:启用保护模式
为1:系统运行在保护模式
为0:系统运行在实模式
关键性:现代操作系统必须设置为1
2. 监控协处理器位
#define CR0_MP (1UL << 1) // 位1 - Monitor Coprocessor
作用:与TS位配合,控制WAIT/FWAIT指令行为
历史用途:用于80386+80287/80387组合
3. 仿真协处理器位
#define CR0_EM (1UL << 2) // 位2 - Emulation
作用:控制浮点指令处理
为1:浮点指令触发异常(由软件模拟)
为0:浮点指令由硬件执行
4. 任务切换位
#define CR0_TS (1UL << 3) // 位3 - Task Switched
作用:指示发生了任务切换
硬件行为:任务切换时自动设置
软件处理:需要手动清除
5. 扩展类型位
#define CR0_ET (1UL << 4) // 位4 - Extension Type
作用:指示协处理器类型
为1:使用80387协处理器
为0:使用80287协处理器
现代系统:通常固定为1
6. 数字错误位
#define CR0_NE (1UL << 5) // 位5 - Numeric Error
作用:控制浮点错误处理
为1:启用原生x87错误报告
为0:使用PC风格错误报告
7. 写保护位
#define CR0_WP (1UL << 16) // 位16 - Write Protect
作用:保护只读页面
为1:禁止内核写入用户只读页面
为0:允许内核写入任何页面
安全意义:实现Copy-on-Write的基础
8. 对齐检查位
#define CR0_AM (1UL << 18) // 位18 - Alignment Mask
作用:启用对齐检查
为1:结合EFLAGS的AC位进行对齐检查
为0:禁用对齐检查
9. 不写透位
#define CR0_NW (1UL << 29) // 位29 - Not Write-through
作用:缓存写策略控制
与CD位配合:控制缓存行为
10. 缓存禁用位
#define CR0_CD (1UL << 30) // 位30 - Cache Disable
作用:禁用处理器缓存
为1:缓存被禁用
为0:缓存启用
11. 分页使能位
#define CR0_PG (1UL << 31) // 位31 - Paging
作用:启用分页机制
为1:启用分页,使用页表转换地址
为0:禁用分页,使用线性地址
关键性:现代操作系统必须设置为1
实际代码示例
Linux 内核中的定义:
/* CR0 位定义 */ #define X86_CR0_PE 0x00000001 // 保护模式使能 #define X86_CR0_MP 0x00000002 // 监控协处理器 #define X86_CR0_EM 0x00000004 // 仿真 #define X86_CR0_TS 0x00000008 // 任务切换 #define X86_CR0_ET 0x00000010 // 扩展类型 #define X86_CR0_NE 0x00000020 // 数字错误 #define X86_CR0_WP 0x00010000 // 写保护 #define X86_CR0_AM 0x00040000 // 对齐检查 #define X86_CR0_NW 0x20000000 // 不写透 #define X86_CR0_CD 0x40000000 // 缓存禁用 #define X86_CR0_PG 0x80000000 // 分页使能
系统启动时的典型设置:
// 启用保护模式和分页 static void setup_cr0(void) {unsigned long cr0 = read_cr0();// 设置关键位cr0 |= CR0_PE; // 保护模式cr0 |= CR0_MP; // 监控协处理器cr0 &= ~CR0_EM; // 禁用仿真(使用硬件FPU)cr0 |= CR0_NE; // 启用原生错误报告cr0 |= CR0_WP; // 启用写保护cr0 |= CR0_PG; // 启用分页// 清除任务切换位(如果有)cr0 &= ~CR0_TS;write_cr0(cr0); }
缓存控制:
// 临时禁用缓存(用于特殊操作) void disable_cache_temporarily(void) {unsigned long cr0 = read_cr0();// 禁用缓存cr0 |= CR0_CD;cr0 |= CR0_NW;write_cr0(cr0);wbinvd(); // 清空缓存// 执行需要无缓存的操作...// 重新启用缓存cr0 &= ~CR0_CD;cr0 &= ~CR0_NW;write_cr0(cr0); }
典型配置场景
现代操作系统配置:
// 标准配置值 #define STANDARD_CR0 (CR0_PE | CR0_MP | CR0_NE | CR0_WP | CR0_PG)
实模式配置:
// 实模式(最低配置) #define REAL_MODE_CR0 (0)
保护模式无分页:
// 保护模式但无分页 #define PROTECTED_MODE_NO_PAGING (CR0_PE | CR0_MP | CR0_NE | CR0_WP)
重要注意事项
PE和PG位:必须按顺序设置(先PE后PG)
缓存控制:修改CD/NW位后需要清空缓存
TS位管理:任务切换后需要正确处理
WP位:对内存保护至关重要
CR0寄存器是x86系统的基础控制核心,直接影响处理器的运行模式、内存管理和系统保护机制。