我有一个关于Linux的深入工作的问题。
比方说一个multithreading进程正在CPU中执行。 在这种情况下,我们将有一个在CPU上执行的线程。 在更宽的画面中,我们将把属于进程的相应页面加载到RAM中执行。
比方说,线程进行系统调用。 在这之后我有点不清楚。 中断将产生一个呼叫。 我的问题之一是谁会回答这个问题?
假设系统有m:n用户级线程到内核级线程映射,我假设相应的内核级线程将回答这个调用。
所以内核将查找中断向量表并获取需要执行的例程。 我的下一个问题是哪个堆栈将用于执行中断? 是内核线程堆栈还是用户级线程堆栈? (我假设它将是内核线程堆栈。)
回到程序的stream程可以说,操作是使用fopen
打开一个文件。 接下来的问题是如何从ISR跳转到系统调用? 或者,我们的ISR映射到系统调用?
当内核线程正在执行的时候,在更宽的画面中,我假设RAM上的“OS区域”将被用来容纳正在执行系统调用的页面。
再次从另一个angular度来看待(希望你仍然和我在一起),最后我假定相应的内核线程正在被CPU调度器处理,其中上下文切换将从用户级线程发生到相应的内核级线程当系统呼叫正在被接听时。
我做了很多假设,如果有人能够澄清这个疑问,或者至less指引我朝着正确的方向,那将是非常棒的。
注意:我主要使用ARM机器工作,所以其中一些可能是ARM特定的。 另外,我会尽可能地尽量简化它。 随时纠正任何可能是错误的或过于简单的。
比方说,线程进行系统调用。 在这之后我有点不清楚。 中断将产生一个呼叫。 我的问题之一是谁会回答这个问题?
通常,处理器将在内核模式的某个预定位置开始执行。 内核将保存当前的进程状态并查看用户空间寄存器,以确定请求哪个系统调用并将其分派给正确的系统调用处理程序。
所以内核将查找中断向量表并获取需要执行的例程。 我的下一个问题是哪个堆栈将用于执行中断? 是内核线程堆栈还是用户级线程堆栈? (我假设它将是内核线程堆栈。)
我很确定它会切换到内核堆栈。 如果他们使用用户空间堆栈,将会有一些非常严重的信息泄漏安全问题。
回到程序的流程可以说,操作是使用fopen打开一个文件。 接下来的问题是如何从ISR跳转到系统调用? 或者,我们的ISR映射到系统调用?
fopen()
实际上是一个libc函数,而不是一个系统调用本身。 它可能(并且在大多数情况下)会在其实现中调用open()
系统调用。
所以,这个过程(大致)是:
fopen()
fopen
执行系统调用open()
当内核线程正在执行的时候,在更宽的画面中,我假设RAM上的“OS区域”将被用来容纳正在执行系统调用的页面。
页面不执行任何操作:)通常,在Linux中,映射在0xC0000000之上的任何地址都属于内核。
再次从另一个角度来看待(希望你仍然和我在一起),最后我假定相应的内核线程正在被CPU调度器处理,其中上下文切换将从用户级线程发生到相应的内核级线程当系统呼叫正在被接听时。
抢占内核,线程有效不受歧视。 据我所知,一个新的线程不是为系统调用服务的目的而创建的 – 它只是运行在与系统调用相同的线程中,除了在内核模式下。
这意味着处于系统调用的内核模式的线程可以被调度出来,就像任何其他线程一样。 因此,在开发内核的时候,这就是你听到“用户空间上下文”的地方。 这意味着它在用户模式线程上以内核模式执行。
这个解释有点难,所以我希望我说得对。