Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

异常处理 (Panic System)

Proka Kernel 采用了一套健壮的异常处理机制,旨在系统发生不可恢复错误时,提供清晰的诊断信息并保护硬件状态。

核心设计

当内核触发 panic! 或发生未捕获的 CPU 异常(如 Page Fault)时,系统会进入 Panic 流程。

1. 状态锁定与现场捕获

在进入 Panic 处理函数的第一时间,内核会执行以下操作:

  • 禁用中断:通过 cli 指令防止嵌套中断干扰。
  • 寄存器快照:捕获触发 Panic 瞬间的通用寄存器(RAX, RBX, RCX…)和关键控制寄存器(RIP, RFLAGS, RSP, RBP)。
  • 异常信息存储:如果是 CPU 中断引起的 Panic,中断处理程序会将异常类型和错误码写入全局的 EXCEPTION_INFO 锁中。

2. 栈回溯 (Stack Backtrace)

为了帮助开发者定位错误,内核实现了基于帧指针(Frame Pointer)的调用栈回溯。

  • 实现机制:通过在编译选项中强制开启帧指针 (-C force-frame-pointers=yes),使编译器在每个函数起始处维护 RBP 链。
  • 回溯逻辑
    1. 捕获当前 RBP
    2. 跳过第一层(Panic 处理器自身)。
    3. 循环迭代:读取 [RBP + 8] 作为返回地址,读取 [RBP] 作为上一层帧指针。
  • 安全性
    • 限制最大深度为 16 层。
    • 验证地址是否处于内核高半区内存空间。
    • 检查地址对齐及链的增长方向,防止死循环。

输出界面

Proka Kernel 提供双重 Panic 信息输出:

图形化蓝屏 (BSoD)

如果帧缓冲(Framebuffer)可用,内核会切换到专用的 Panic 控制台(功能简陋),并在屏幕上绘制:

  • 错误原因:Panic 宏提供的字符串消息。
  • 源代码位置:触发错误的文件名 and 行号。(依赖于Rust的core,可能不是真正的源码位置)
  • 系统状态:开机时长、关键寄存器状态。
  • 通用寄存器:十六进制显示的寄存器列表。
  • 调用栈:回溯得到的地址列表。

串口输出

所有 Panic 信息也会同步发送到串口 (Serial Port),方便通过开发机日志捕捉。

调试建议

当看到栈回溯地址时,可以使用 addr2line 工具配合内核 ELF 文件进行解析:

# 将 0xffffffff80001234 替换为实际的回溯地址
addr2line -e output/kernel 0xffffffff80001234

测试模式下的 Panic

在单元测试模式下,Panic 处理器会重定向到测试框架。它会打印错误信息并执行 long_jmp 跳回测试调度器,从而允许测试套件继续运行后续测试项,而不是直接挂起整个系统。