1. 实验背景与核心目标
在Linux操作系统的内存管理机制中,分页(Paging)是最基础也是最关键的技术之一。这个实验聚焦于分页机制下代码段和数据段的权限控制问题,特别是它们与页表权限位(Page Table Permission Bits)的关联关系。通过这个实验,我们可以深入理解:
- 为什么用户态程序不能随意修改内核空间的数据?
- 为什么代码段通常被标记为不可写?
- 当程序尝试越权访问内存时,硬件和操作系统如何协同工作来阻止这种非法行为?
这个实验适合已经掌握Linux基础内存管理概念,想进一步理解保护模式(Protected Mode)下权限控制机制的同学。我们将通过编写测试程序、观察页表项(Page Table Entry)变化、触发页错误(Page Fault)等方式,直观感受权限位的实际作用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关键概念解析
2.1 分页机制中的权限位
在x86架构的分页机制中,每个页表项(无论是PDE还是PTE)都包含一组控制权限的标志位:
code复制31 12 11 9 8 7 6 5 4 3 2 1 0
+-------------------+-----+-+-+-+-+-+-+-+-+-+
| Page Frame Addr | AVL |D|A|C|U|W|P|U|R|P|
+-------------------+-----+-+-+-+-+-+-+-+-+-+
关键权限位说明:
- P (Present):页是否存在于物理内存中
- R/W (Read/Write):0=只读,1=可读可写
- U/S (User/Supervisor):0=内核态可访问,1=用户态可访问
2.2 段描述符中的权限控制
在保护模式下,段描述符(Segment Descriptor)也包含权限控制字段:
code复制+-----------------+---+---+---+---+---+---+---+---+
| Base 31:24 | G |D/B| L |AVL|Limit 19:16| P |
+-----------------+---+---+---+---+---+---+---+---+
| Base 23:16 | DPL | S | Type | Base 15:0 |
+-----------------+-----+---+------+------------+
| Limit 15:0 | Base 15:0 |
+-----------------+-----------------------------+
关键字段:
- DPL (Descriptor Privilege Level):描述符特权级(0-3)
- Type字段:包含E(Executable)、C(Conforming)、R(Readable)、W(Writable)等权限标记
2.3 权限检查的完整流程
当CPU执行内存访问时,完整的权限检查流程如下:
- 段选择子检查:确保CPL ≤ DPL
- 段类型检查:例如代码段不可写
- 页表权限检查:确保访问方式(R/W)与页表项权限匹配
- 用户/内核权限检查:U/S位决定用户态是否能访问
重要提示:最终生效的权限是段权限和页权限的"与"关系。例如,即使页表项标记为可写,如果段描述符标记为只读,那么实际访问仍然是只读的。
3. 实验环境准备
3.1 硬件与软件需求
- 支持x86-64架构的CPU(现代Intel/AMD处理器均可)
- Linux内核版本4.x或更高(推荐5.x系列)
- GCC编译器套件
- 需要root权限执行部分操作
3.2 内核模块开发环境配置
我们需要编写一个简单的内核模块来查看页表内容:
bash复制# 安装开发工具链
sudo apt update
sud
