linux kernel struct 之 pt_regs
2026/9/24 17:38:18 网站建设 项目流程

struct pt_regs是 Linux 内核中用于保存 CPU 寄存器现场的核心数据结构。当发生系统调用、中断或异常时,CPU 的寄存器状态会被保存到栈上的这个结构体中,内核据此了解“进入内核前用户态在做什么”,并在返回时恢复现场。

核心作用

  • 系统调用:用户态通过syscall指令进入内核,硬件自动将部分寄存器保存到pt_regs,内核从中读取系统调用号和参数。

  • 中断/异常:CPU 触发中断或异常时,硬件和入口汇编代码协作,将寄存器压栈形成pt_regs,内核处理完后通过它恢复用户态。

  • 信号处理:向用户态进程发送信号时,内核修改pt_regs中的ipsp等字段,使进程在返回用户态时跳转到信号处理函数。

x86_64 下的结构定义

在 x86_64 架构中,struct pt_regs的定义位于arch/x86/include/asm/ptrace.h,其字段顺序严格对应硬件压栈的顺序(从高地址到低地址):

struct pt_regs { /* * 用户态返回时,部分寄存器由硬件自动压栈(顺序固定): * SS, RSP, RFLAGS, CS, RIP(发生特权级切换时) */ unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; // RBP unsigned long bx; // RBX unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; // RAX unsigned long cx; // RCX unsigned long dx; // RDX unsigned long si; // RSI unsigned long di; // RDI unsigned long orig_ax; // 系统调用号(或原始 RAX) unsigned long ip; // RIP(指令指针) unsigned long cs; // 代码段选择子 unsigned long flags; // RFLAGS unsigned long sp; // RSP(栈指针) unsigned long ss; // 栈段选择子 };

关键字段解读

字段含义
ip触发异常或系统调用时的指令地址。信号处理时,内核会修改它来跳转到信号处理函数。
sp用户态栈指针。进入内核时由硬件保存,返回时恢复。
flagsRFLAGS 寄存器,包含中断使能、方向标志等。
orig_ax系统调用号。syscall入口会将原始rax(系统调用号)保存到这里,之后ax可被返回值覆盖。
ax~r15通用寄存器。系统调用参数依次存放在disidxr10r8r9中。

user_mode()的关系

内核通过检查pt_regs->cs的最低两位(CPL)来判断异常来自用户态还是内核态:

static inline int user_mode(struct pt_regs *regs) { return (regs->cs & 3) != 0; }

这是缺页异常处理中区分“用户地址故障”和“内核地址故障”的关键依据。

在缺页异常处理中的角色

do_user_addr_fault(regs, error_code, address)中的regs就是struct pt_regs *。它提供了:

  • regs->ip:定位触发缺页的指令(用于is_prefetch检测、show_signal_msg日志)。

  • regs->sp:判断是否涉及栈扩展(VM_GROWSDOWN)。

  • user_mode(regs):决定走用户态还是内核态的故障处理路径。

struct pt_regs是内核与硬件、用户态之间的“寄存器快照”,几乎所有与异常、中断、系统调用相关的代码都围绕它展开。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询