保存中断上下文
【保存中断上下文】
处理器总是处于如下状态当中的其一:
1.用户态:运行域用户空间。
2.内核态:运行于进程的上下文,内核代表进程运行于内核空间。
3.内核态:运行域中断上下文,内核代表硬件运行于内核空间。
1. 进程上下文(Process Context)
概念:
进程上下文是进程运行时所需的环境信息,包括寄存器值、内存状态、打开的文件等。当内核切换进程时,必须保存当前进程的所有状态(即进程上下文),以便后续恢复执行。核心内容:
寄存器上下文:程序计数器(IP)、栈指针(ESP)、状态寄存器(EFLAGS)。
内存信息:代码段、数据段、用户堆栈、共享内存等。
系统资源:进程控制块(
task_struct
)、内存管理结构(mm_struct
)、内核栈等。案例:
假设Linux系统中正在运行两个进程:进程A
(浏览器)和进程B
(音乐播放器)。
当CPU从
进程A
切换到进程B
时,内核会:
保存
进程A
的寄存器值到其task_struct
中。将内存管理信息保存到
mm_struct
。加载
进程B
的上下文,恢复其执行。这一过程称为上下文切换,由调度器触发,保证了多任务的并发执行。
2. 线程上下文(Thread Context)
概念:
线程上下文是线程运行时所需的环境信息,包括寄存器值、栈指针、线程控制块等。线程是进程内的执行单元,共享进程的资源(如内存、文件),因此线程上下文切换的开销通常比进程更小。核心内容:
寄存器上下文:程序计数器(IP)、栈指针(ESP)、状态寄存器(EFLAGS)。
线程私有资源:线程栈(存储局部变量、函数调用链)、线程控制块(
thread_info
或pthread_t
)。共享资源:进程的代码段、数据段、打开的文件、内存管理结构(如
mm_struct
)等。与进程上下文的对比:
对比项 进程上下文 线程上下文 资源隔离性 独立内存空间、文件等 共享进程的内存和文件资源 切换开销 高(需切换页表、刷新TLB等) 低(无需切换内存管理信息) 核心数据结构 task_struct
(进程控制块)thread_info
(线程控制块)案例:
在浏览器进程(进程A)中,有两个线程:
线程1:渲染页面(解析HTML/CSS)。
线程2:处理网络请求(下载图片)。
当CPU从线程1切换到线程2时:
保存线程1的寄存器到其线程控制块。
无需保存内存管理信息(共享进程的
mm_struct
)。加载线程2的寄存器和栈地址,恢复执行。
3. 中断上下文(Interrupt Context)
概念:
中断上下文是硬件触发中断时内核处理程序所需的临时环境。它不关联任何进程,因此不能直接访问进程资源(如用户空间内存)。特点:
快速执行(不能休眠或调用可能阻塞的函数)。
不能访问用户空间数据(需通过内核接口)。
案例:
当用户按下键盘时,硬件触发中断:
CPU暂停当前进程(如浏览器),进入中断处理程序。
内核保存当前进程的上下文(如寄存器),但中断处理程序自身运行在中断上下文。
中断程序读取键盘缓冲区数据,标记为“待处理”。
中断结束后,内核可能触发调度,恢复原进程或切换到其他进程。
4. 进程上下文的三个部分
具体分解:
用户级上下文:
包括代码(正文段)、全局变量(数据段)、用户堆栈。
案例:一个运行中的C程序,其代码和全局变量存储在用户空间的内存中。
寄存器上下文:
关键寄存器:ESP(栈指针)、IP(程序计数器)、EFLAGS(状态寄存器)。
案例:进程执行到
printf
函数时,IP指向printf
的地址,ESP指向函数调用的栈帧。系统级上下文:
task_struct
:包含进程ID、优先级、状态等信息。
mm_struct
:管理进程的虚拟内存布局(如堆、栈的地址范围)。案例:进程调用
malloc
申请内存时,内核通过mm_struct
分配新的虚拟内存区域。
5. 保存中断上下文与EL0/EL1的区别
机制:
kernel_entry
宏:在ARM架构中,根据异常级别(EL0或EL1)保存不同上下文:
EL0(用户态异常):如系统调用(用户程序触发
open()
)。
需要保存用户空间的寄存器(如x0-x30)。
EL1(内核态异常):如硬件中断(定时器到期)。
仅保存必要的内核寄存器。
案例:
系统调用(EL0):
用户程序执行read()
系统调用时,CPU从EL0切换到EL1。
kernel_entry
保存用户寄存器,内核处理完read()
后恢复现场。硬件中断(EL1):
网卡接收到数据包时触发中断,内核直接保存当前内核栈的寄存器,处理中断后恢复。
https://github.com/0voice