本节摘要:特权架构的第一根支柱是身份制度——机器、监督、用户三级模式规定谁能动全局状态;第二根支柱是登记簿——控制状态寄存器群集中存放全局状态,配一套专用读写指令;两者合起来,"运行操作系统"这件事才有了硬件落点。本节讲清模式分工、切换规则、寄存器地址空间的编码巧思与核心寄存器档案袋。
先给定义:特权模式是处理器当前执行状态的一个硬件属性,它决定了当前指令能访问哪些控制状态寄存器、能执行哪些特权指令、能触碰哪些内存区域。没有身份制度的处理器上,任何程序都能改中断向量表、直写设备寄存器——一个野指针就能把整台机器掀翻。身份制度把"能掀桌子"的权力收归最高特权级,操作系统在中间层调度,应用在最底层活动。
三级模式的分工:机器模式是硬件主权层,上电复位即处于此级,固件与引导代码在这里初始化一切,它看得见整台机器;监督模式是为操作系统内核设计的层,拥有页表与虚拟内存的管理权;用户模式是应用的囚笼,任何越权访问都会触发陷入、被上层接管。嵌入式小系统可以只用机器模式裸奔,通用系统三层全开——层级按需取用,又是模块化哲学的一处落点。

全局状态需要一个集中登记处:中断向量在哪、当前模式是什么、计时器读数多少——这些不归程序计数器与通用寄存器管的东西,全部登记在控制状态寄存器里。它们是独立的地址空间,与内存地址无关,用一套专用指令读写:
csrrw t0, mstatus, t1 # 原子交换:读旧值进 t0,写入 t1 的新值 csrrs t0, mie, t2 # 读并置位:把 t2 中为 1 的位置 1,旧值回 t0 csrrc t0, mstatus, t3 # 读并清位:把 t3 中为 1 的位清 0,旧值回 t0 csrrwi t0, mie, 5 # 立即数版本:置位掩码直接编码在指令里
这套指令设计的巧思在原子性:读改写一拍完成,不需要"读—改—写"三步间担心被中断打断。地址空间的编码也有讲究:寄存器地址的高位段标明访问权限(哪一级模式可读写)与只读属性,译码器可以直接从地址推出访问检查规则——又一次"编码即结构"的设计手法,与第二章指令格式的对齐思路一脉相承。
每个模式有自己的档案袋,核心几件套结构相同、前缀不同(机器级一组、监督级一组):
| 档案项 | 作用 | 陷入时硬件自动做什么 |
|---|---|---|
| 状态寄存器 | 当前模式、全局中断使能等 | 保存旧模式与旧中断状态 |
| 陷入向量基址 | 陷入处理入口的地址 | 程序计数器跳到基址指向的入口 |
| 陷入原因寄存器 | 编码这次陷入是异常还是中断、具体编号 | 写入本次事件的编号 |
| 陷入程序计数器 | 存放被打断指令的地址 | 写入被打断处的地址 |
| 中断使能寄存器 | 每个中断源的开关位 | 不动,由处理程序按需操作 |
硬件自动做前三件(改状态、跳入口、记原因与位置),软件处理程序接着保存通用寄存器、处理事件、恢复现场、执行返回指令——返回指令从档案袋里取回旧身份与旧位置,机器回到被打断的地方。一次陷入的完整旅程,就是硬件与软件围绕这个档案袋的交接仪式,下一节把这条旅程放进流水线里逐拍看。
💡 关键直觉:特权架构的设计美学是"硬件做最少的自动化"——只自动做必须原子的事(记账与跳转),其余全部留给软件。这保证了硬件简单、软件策略灵活,与第一章"合约只锁最小内核"的哲学同源。
登记簿虽好,访问它不是免费的。控制状态寄存器的读写通常要求串行化:读写指令之前的所有指令完成、之后的指令等它完成——因为 CSR 改变的往往是全局状态(中断使能、翻译模式),乱序执行它们会造成语义混乱。实现上,CSR 指令在流水线里是"清障车"角色:停在执行站,等前面清空,完成访问,再放后面通过。频繁读写 CSR 的代码(比如每条消息都开关中断)会明显感受到这份代价——优化方向在软件侧:批量开关、按临界区粗粒度操作、能用通用寄存器暂存的状态就不要往返 CSR。这段讨论也提前给 5.2 的"精确打断"铺了路:CSR 串行化与异常裁决共享同一套"按序完成"机制。
读一节的验收练习:合上书,默画三格模式图(身份、分工、切换路径),再默写档案袋五件套与陷入时的硬件动作。画得全,说明身份制度与登记簿已经内化;画不全的部分,正好是你该重读的段落。
问:机器模式可以直接跳去执行用户代码吗? 技术上可以切到低模式再执行,但"用高身份跑不可信代码"是安全大忌——固件的职责是管理机器,不是替应用干活。设计良好的系统里,机器模式代码量被压到最小,越小越可审计。
问:不同模式的寄存器是分开的吗? 通用寄存器全模式共用一套——切换不自动保存它们(所以才需要软件保存现场的"交接仪式");控制状态寄存器则是每模式一套自己的档案袋。共用加分立,正是"硬件做最少自动化"的又一处体现。
把本节最核心的机制压成四句口诀,方便上板调试时默诵:陷入必记账——原因、位置、旧状态,硬件一拍写好;返回靠档案——返回指令取回身份与地址,一步到位;现场自己搬——通用寄存器归软件管,处理程序进出各搬一次;模式不越级——身份只经陷入与返回两条门改换,任何指令伪造不了特权。调试启动问题时,逐句核对这四条哪条被违反,八成的疑难杂症能当场定位。
动手建议:跟练本节最有效的方式是在模拟器里跑一段"最小陷入之旅"——写一个触发非法指令的小程序,用调试器观察陷入前后的档案袋变化:原因寄存器里出现什么编号、程序计数器寄存器存着哪条指令的地址、状态寄存器的模式位怎么翻。半小时的观察,胜过十遍文字推演。
身份制度立好了,下一节看什么事件会触发切换、切换在流水线里怎么做成一场精确的手术。