Linux系统调用流程序列

我有一个关于Linux深入工作的问题.

假设在CPU中正在执行多线程进程.在这种情况下,我们将有一个在CPU上执行的线程.在更广泛的图片中,我们将属于Process的相应页面加载到RAM中以供执行.

让我们说线程进行系统调用.我对此之后的运作有点不清楚.中断将生成一个呼叫.我的一个问题是谁将接听这个电话?

让我们说系统有m:n用户级线程到内核级线程映射,我假设相应的内核级线程将回答此调用.

因此,内核将查找中断向量表并获取需要执行的例程.我的下一个问题是在执行中断时将使用哪个堆栈?它是内核线程的堆栈还是用户级别的线程堆栈? (我假设它将是内核线程的堆栈.)

回到程序流程可以说操作是使用fopen打开文件.我接下来的问题是如何从ISR跳转到系统调用?或者我们的ISR是否映射到系统调用?

当内核线程正在执行时,我还假设RAM上的“OS区域”将用于容纳正在执行系统调用的页面.

再次从不同的角度看待它(希望你还在我身边)最后我假设相应的内核线程正在由CPU调度程序处理,在这里,从用户级线程到相应的内核级线程的上下文切换当fopen系统调用被回答时.

我已经做了很多假设,如果有人能够清除疑虑或者至少引导我朝着正确的方向前进,那绝对是太棒了.

最佳答案
注意:我主要使用ARM机器,因此其中一些可能是ARM特定的.另外,我将尽可能地尝试简化它.随意纠正任何可能错误或过于简单的事情.

Lets say the thread makes a system call. I am a bit unclear on the workings after this. The Interrupt will generate a call. One of my questions is who will answer this call?

通常,处理器将在内核模式中的某个预定位置开始执行.内核将保存当前进程状态并查看用户空间寄存器以确定请求了哪个系统调用并将其分派给正确的系统调用处理程序.

So the Kernel will lookup the Interrupt Vector Table and get the routine which needs to be executed. My next question is which stack will be used in the execution of the Interrupt? Will it be the Kernel Thread’s Stack or the User level Thread’s Stack? (I am assuming that it will be the Kernel Thread’s Stack.)

我很确定它会切换到内核堆栈.如果使用用户空间堆栈,那么信息泄漏会有一些非常严重的安全问题.

Coming back to the flow of the program lets say the operation is opening a file using fopen. The subsequent question I have is how will the jump from the ISR to System Call take place? Or is our ISR mapped to a System Call?

fopen()实际上是一个libc函数,而不是系统调用本身.它可能(在大多数情况下会)在其实现中调用open()系统调用.

所以,这个过程(大致)是:

>用户空间调用fopen()
> fopen执行系统调用open()
>这会触发某种异常或中断.作为响应,处理器切换到更特权模式并开始在内核中的某个预设位置执行.
> Kernel确定它是什么类型的中断和异常并适当地处理它.在我们的例子中,它将是一个系统调用.
>内核通过读取用户空间寄存器来确定正在请求的系统调用,并提取任何参数并将其传递给适当的处理程序.
>处理程序运行.
> Kernel将任何返回码放入用户空间寄存器.
>内核将执行转移回发生异常的位置.

Also at a more broader picture when the Kernel Thread is being executed I am assuming that the “OS region” on the RAM will be used to house the pages which are executing the System Call.

页面不执行任何操作:)通常,在Linux中,映射到0xC0000000以上的任何地址都属于内核.

Again looking at it from a different angle (Hope your still with me) finally I am assuming that the corresponding Kernel Thread is being handled by the CPU Scheduler where in a context switch would have happened from the User Level Thread to the corresponding Kernel Level Thread when the fopen System Call was being answered.

使用抢占式内核,有效地不会区分线程.根据我的理解,不是为了服务系统调用而创建一个新线程 – 它只是在请求系统调用的同一个线程中运行,除了内核模式.

这意味着处于为系统调用提供服务的内核模式的线程可以与任何其他线程一样进行调度.因此,这是您在为内核开发时听到“用户空间上下文”的地方.这意味着它在用户模式线程上以内核模式执行.

这有点难以解释,所以我希望我做对了.

转载注明原文:Linux系统调用流程序列 - 代码日志