Linux 提供了 glibc 库, 它封装了系统调用接口, 对上层更友好的提供服务, 系统调用最终都会通过 DO_CALL 发起, 这是一个宏定义, 其 32 位和 64 位的定义是不同的:
32 位系统调用
用户态
将请求参数保存到寄存器
将系统调用名称转为系统调用号保存到寄存器 eax 中
通过软中断 ENTER_KERNEL 陷入内核态
内核态
内核的软中断陷入门收到系统调用会将用户态的寄存器保存到 pt_regs 结构中
在系统调用函数表 sys_call_table 中根据调用号找到对应的函数
并将寄存器中保存的参数取出来作为参数执行函数, 将返回值写入 pt_regs 结构的 ax 位置
通过iret指令根据 pt_regs 恢复用户态进程
64 位系统调用
用户态
将请求参数保存到寄存器
将系统调用名称转为系统调用号保存到寄存器 rax 中
通过 syscall 指令进入内核态
(注:由int中断指令改为syscall指令,减少了一次查表过程,性能应该有所提高)
内核态
将用户态的寄存器保存到 pt_regs 中
在系统调用函数表 sys_call_table 中根据调用号找到对应的函数
将寄存器中保存的参数取出来作为函数参数执行函数, 将返回值写入 pt_regs 的 ax 位置
在系统结构中,CPU工作的模式有两种,一种是中断,由各种设备发起;一种是轮询,由CPU主动发起。中断IRQ:
中断允许让设备(如键盘,串口卡,并口等设备)表明它们需要CPU。一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。CPU处理完中断后,就会恢复执行之前被中断的程序。
中断分类:
硬中断+软中断
硬中断:
①非屏蔽中断:不能被屏蔽,硬件发生的错误:内存错误,风扇故障,温度传感器故障等。
②可屏蔽中断:可被CPU忽略或延迟处理。当缓存控制器的外部针脚被触发的时候就会产生这种类型的中断,而中断屏蔽寄存器就会将这样的中断屏蔽掉。我们可以将一个比特位设置为0,来禁用在此针脚触发的中断。
软中断:
是软件实现的中断,也就是程序运行时其他程序对它的中断而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
CPU之间的中断处理(IPI)
处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
CALL_FUNCTION_VECTOR (向量0xfb)
发往所有的CPU,但不包括发送者,强制这些CPU运行发送者传递过来的函数,相应的中断处理程序叫做call_function_interrupt(),例如,地址存放在群居变量call_data中来传递的函数,可能强制其他所有的CPU都停止,也可能强制它们设置内存类型范围寄存器的内容。通常,这种中断发往所有的CPU,但通过smp_call_function()执行调用函数的CPU除外。
RESCHEDULE_VECTOR (向量0xfc)
当一个CPU接收这种类型的中断时,相应的处理程序限定自己来应答中断,当从中断返回时,所有的重新调度都自动运行。
INVALIDATE_TLB_VECTOR (向量0xfd)
发往所有的CPU,但不包括发送者,强制它们的转换后援缓冲器TLB变为无效。相应的处理程序刷新处理器的某些TLB表项。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)