当线程通过引发中断80进行系统调用时会发生什么(详细)? Linux对线程的堆栈和其他状态做了哪些工作?对处理器进行了哪些更改以使其进入内核模式?运行中断处理程序后,控制如何恢复到调用进程?
如果无法快速完成系统调用,该怎么办?从磁盘读取。中断处理程序如何放弃控制,以便处理器在加载数据时可以执行其他操作以及如何再次获取控制权?
答案 0 :(得分:38)
好问题! (面试问题?)
int $ 80操作模糊地像函数调用。 CPU“占用陷阱”并在内核模式下以已知地址重新启动,通常也使用不同的MMU模式。内核将保存许多寄存器,但它不必保存程序不希望普通函数调用保存的寄存器。
通常,OS会保存ABI承诺在过程调用期间不会更改的寄存器。堆栈将保持不变;内核将在每个线程的内核堆栈上运行,而不是在每个线程的用户堆栈上运行。当然,某些州会发生变化,否则就没有理由进行系统调用。
这通常是完全自动的。 CPU通常具有软件中断指令,有点像功能调用操作。它将导致在受控条件下切换到内核模式。通常,CPU会更改某种PSW保护位,保存旧的PSW和PC,从众所周知的陷阱向量地址开始,也可以切换到不同的内存管理保护和映射排列。
通常会有某种“从中断返回”或“从陷阱返回”指令,它有点像复杂的函数返回指令。一些RISC处理器自动执行很少并且需要特定代码来执行返回,并且一些像x86这样的CISC处理器具有(从未真正使用过的)指令,这些指令将执行在架构 - 手动伪代码页面中记录的许多操作以进行功能调整。
内核本身的线程很像线程用户程序。它只是切换堆栈(线程)并在其他人的进程上运行一段时间。
答案 1 :(得分:7)
回答问题的最后部分 - 如果系统调用需要休眠,内核会做什么 -
在系统调用之后,内核仍然在进行系统调用的同一任务的上下文中逻辑运行 - 它只是在内核模式而不是用户模式 - 它不是一个单独的线程,大多数系统调用都不会调用来自另一个任务/线程的逻辑。会发生什么是系统调用调用wait_event,wait_event_timeout或其他一些等待函数,它将任务添加到等待某事的任务列表中,然后将任务置于睡眠状态,这会改变其状态,并调用schedule()来放弃当前的CPU。
在此之后,任务无法再次运行,直到它被唤醒,通常由另一个任务(内核任务等)或中断处理程序调用唤醒*函数,该函数将唤醒等待该特定事件的任务。 ,这意味着调度程序将很快再次安排它们。
值得注意的是,用户空间任务(即线程)只是一种类型的任务,并且内核中还有一些内核可以正常工作 - 这些是内核线程和下半部分处理程序/ tasklet /任务队列等不属于任何特定用户空间进程的工作(例如网络处理,例如响应ping)在这些工作中完成。与中断(不应调用调度程序)不同,允许这些任务进入休眠状态
答案 2 :(得分:3)
答案 3 :(得分:0)
这应该有助于那些寻求答案的人在执行syscall
指令时将控件转移到内核(用户模式到内核模式)。这基于x86_64架构。
https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-2.html