简体   繁体   English

Linux系统调用的内部

[英]Internals of a Linux system call

What happens (in detail) when a thread makes a system call by raising interrupt 80? 当线程通过引发中断80进行系统调用时会发生什么(详细)? What work does Linux do to the thread's stack and other state? Linux对线程的堆栈和其他状态做了哪些工作? What changes are done to the processor to put it into kernel mode? 对处理器进行了哪些更改以使其进入内核模式? After running the interrupt handler, how is control restored back to the calling process? 运行中断处理程序后,控制如何恢复到调用进程?

What if the system call can't be completed quickly: eg a read from disk. 如果系统调用无法快速完成,例如从磁盘读取,该怎么办? How does the interrupt handler relinquish control so that the processor can do other stuff while data is being loaded and how does it then obtain control again? 中断处理程序如何放弃控制,以便处理器在加载数据时可以执行其他操作,以及如何再次获取控制权?

A crash course in kernel mode in one stack overflow answer 内核模式中的崩溃过程在一个堆栈溢出答案中

Good questions! 好问题! (Interview questions?) (面试问题?)


  • What happens (in detail) when a thread makes a system call by raising interrupt 80? 当线程通过引发中断80进行系统调用时会发生什么(详细)?

The int $80 operation is vaguely like a function call. int $ 80操作模糊地像函数调用。 The CPU "takes a trap" and restarts at a known address in kernel mode, typically with a different MMU mode as well. CPU“占用陷阱”并在内核模式下以已知地址重新启动,通常也使用不同的MMU模式。 The kernel will save many of the registers, though it doesn't have to save the registers that a program would not expect an ordinary function call to save. 内核将保存许多寄存器,但它不必保存程序不希望普通函数调用保存的寄存器。

  • What work does Linux do to the thread's stack and other state? Linux对线程的堆栈和其他状态做了哪些工作?

Typically an OS will save registers that the ABI promises not to change during procedure calls. 通常,OS将保存ABI承诺在过程调用期间不会更改的寄存器。 The stack will stay the same; 堆栈将保持不变; the kernel will run on a per-thread kernel stack rather than the per-thread user stack. 内核将在每个线程的内核堆栈上运行,而不是在每个线程的用户堆栈上运行。 Naturally some state will change, otherwise there would be no reason to do the system call. 当然有些州会改变,否则就没有理由进行系统调用。

  • What changes are done to the processor to put it into kernel mode? 对处理器进行了哪些更改以使其进入内核模式?

This is usually entirely automatic. 这通常是完全自动的。 The CPU has, generically, a software-interrupt instruction that is a bit like a functional-call operation. CPU通常具有软件中断指令,有点像功能调用操作。 It will cause the switch to kernel mode under controlled conditions. 它将导致在受控条件下切换到内核模式。 Typically, the CPU will change some sort of PSW protection bit, save the old PSW and PC, start at a well-known trap vector address, and may also switch to a different memory management protection and mapping arrangement. 通常,CPU会更改某种PSW保护位,保存旧的PSW和PC,从众所周知的陷阱向量地址开始,并且还可以切换到不同的存储器管理保护和映射排列。

  • After running the interrupt handler, how is control restored back to the calling process? 运行中断处理程序后,控制如何恢复到调用进程?

There will be some sort of "return from interrupt" or "return from trap" instruction, typically, that will act a bit like a complicated function-return instruction. 通常会有某种“从中断返回”或“从陷阱返回”指令,这有点像复杂的函数返回指令。 Some RISC processors did very little automatically and required specific code to do the return and some CISC processors like x86 have (never-really-used) instructions that would execute dozens of operations documented in pages of architecture-manual pseudo-code for capability adjustments. 一些RISC处理器自动执行很少并且需要特定代码来执行返回,并且一些像x86这样的CISC处理器具有(从未真正使用过的)指令,这些指令将执行在架构 - 手动伪代码页面中记录的许多操作以进行功能调整。

  • What if the system call can't be completed quickly: eg a read from disk. 如果系统调用无法快速完成,例如从磁盘读取,该怎么办? How does the interrupt handler relinquish control so that the processor can do other stuff while data is being loaded and how does it then obtain control again? 中断处理程序如何放弃控制,以便处理器在加载数据时可以执行其他操作,以及如何再次获取控制权?

The kernel itself is threaded much like a threaded user program is. 内核本身的线程很像线程用户程序。 It just switches stacks (threads) and works on someone else's process for a while. 它只是切换堆栈(线程)并在其他人的进程上工作一段时间。

To answer the last part of the question - what does the kernel do if the system call needs to sleep - 回答问题的最后部分 - 如果系统调用需要睡眠,内核会做什么 -

After a system call, the kernel is still logically running in the context of the same task that made the system call - it's just in kernel mode rather than user mode - it is NOT a separate thread and most system calls do not invoke logic from another task/thread. 在系统调用之后,内核仍然在进行系统调用的同一任务的上下文中逻辑运行 - 它只是在内核模式而不是用户模式 ​​- 它不是一个单独的线程,并且大多数系统调用不会从另一个调用逻辑任务/线程。 What happens is that the system call calls wait_event, or wait_event_timeout or some other wait function, which adds the task to a list of tasks waiting for something, then puts the task to sleep, which changes its state, and calls schedule() to relinquish the current CPU. 会发生什么是系统调用调用wait_event,wait_event_timeout或其他一些等待函数,它将任务添加到等待某事的任务列表中,然后将任务置于睡眠状态,这会改变其状态,并调用schedule()来放弃当前的CPU。

After this the task cannot be run again until it gets woken up, typically by another task (kernel task, etc) or interrupt handler calling a wake* function which will wake up the task(s) sleeping waiting for that particular event, which means the scheduler will soon schedule them again. 在此之后,任务无法再次运行,直到它被唤醒,通常由另一个任务(内核任务等)或中断处理程序调用唤醒*函数,该函数将唤醒等待该特定事件的任务,这意味着调度程序将很快再次安排它们。

It's worth noting that userspace tasks (ie threads) are only one type of task and there are a few others internal to the kernel which can do work as well - these are kernel threads and bottom half handlers / tasklets / task queues etc. Work which doesn't belong to any particular userspace process (for example network handling eg responding to pings) gets done in these. 值得注意的是,用户空间任务(即线程)只是一种类型的任务,并且内核中还有一些内核可以正常工作 - 这些是内核线程和下半部分处理程序/ tasklet /任务队列等。不属于任何特定用户空间进程(例如网络处理,例如响应ping)在这些进程中完成。 These tasks are allowed to go to sleep, unlike interrupts (which should not invoke the scheduler) 与中断(不应调用调度程序)不同,允许这些任务进入休眠状态

This should help people who seek for answers to what happens when the syscall instruction is executed which transfers the control to the kernel (user mode to kernel mode). 这应该有助于那些寻求对执行syscall指令时发生的事情的答案的人,这些指令将控制转移到内核(用户模式到内核模式)。 This is based upon x86_64 architecture. 这基于x86_64架构。

https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-2.html https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-2.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM