Linux中的系统调用如何实现?

当我以用户模式调用系统调用时,如何在OS中处理这个调用?

它是否调用一些可执行二进制文件或一些标准库?

如果是的话,完成这个呼叫需要什么样的东西?

看看这个 。

从2.5版开始,linux内核在Pentium II +处理器上引入了一个新的系统调用入口机制。 由于现有软件中断方法在Pentium IV处理器上的性能问题,使用Pentium II +处理器上提供的SYSENTER / SYSEXIT指令实现了另一种系统调用入口机制。 本文探讨了这种新机制。 讨论仅限于x86架构,所有源代码列表都基于Linux内核2.6.15.6。

  1. 什么是系统调用?

    系统调用为用户态进程提供了从内核请求服务的方式。 什么样的服务? 由操作系统pipe理的服务,如存储,内存,networking,进程pipe理等。例如,如果用户进程想要读取一个文件,就必须进行“打开”和“读取”系统调用。 通常,系统调用不会被进程直接调用。 C库提供了一个所有系统调用的接口。

  2. 系统调用会发生什么?

    内核代码片段是根据用户进程的请求运行的。 此代码运行于环形0(具有当前特权级别-CPL-0),这是x86体系结构中的最高级别特权。 所有用户进程都运行在环3(CPL 3)中。

    所以,要实现系统调用机制,我们需要的是

    1)从环3呼叫环0码的方式。

    2)一些内核代码来处理请求。

  3. 古老的做法

    直到一段时间之后,linux才使用软件中断在所有x86平台上实现系统调用。 要执行系统调用,用户进程会将所需的系统调用号复制到%eax,并执行“int 0x80”。 这将产生中断0x80,并将调用中断服务程序。 对于中断0x80,这个例程是一个“所有系统调用处理”例程。 此例程将在环0中执行。此例程(如/usr/src/linux/arch/i386/kernel/entry.S中所定义)将保存当前状态,并根据%中的值调用相应的系统调用处理程序。 EAX。

  4. 新的shiny的方式做到这一点

    发现这种软件中断方法在奔腾IV处理器上要慢得多。 为了解决这个问题,Linus实现了一个替代的系统调用机制来利用所有Pentium II +处理器提供的SYSENTER / SYSEXIT指令。 在进一步研究这种新的方法之前,让我们让自己更熟悉这些说明。

这取决于你的系统调用的意思。 你是指C库调用(通过glibc)还是实际的系统调用? C库调用最终总是最终使用系统调用。

进行系统调用的旧方法是通过软件中断,即int指令。 Windows有int 0x2e而Linux有int 0x80 。 OS在中断描述符表(IDT)中为0x2e或0x80build立中断处理程序。 这个处理程序然后执行系统调用。 它将用户模式的参数复制到内核模式(这是由操作系统特定的约定来控制的)。 在Linux上,使用ebxecxedxesiedi传递参数。 在Windows上,参数是从堆栈复制的。 处理程序然后执行某种查找(查找函数的地址)并执行系统调用。 系统调用完成后, iret指令返回到用户模式。

新的方法是sysexitsysexit 。 这两条指令基本上为你做所有的注册工作。 OS通过模型特定寄存器(MSR)设置指令。 之后,它几乎和使用int相同。

它通过glibc,在用参数填充寄存器之后发出0x80中断。 内核的中断处理程序然后在syscall表中查找系统调用并调用相关的sys _ *()函数。

非常简单,但是当您尝试访问保留的内存地址时会发生中断。 中断将上下文切换到内核模式,并代表用户执行内核代码(实际系统调用)。 一旦通话完成,控制返回到用户代码。

assembly中的int X转换为系统调用编号n。
读取系统调用可能会给出一个数字4。
在系统启动时,OSbuild立一个叫做中断描述符表(IDT)的指针表,它具有系统调用的地址列表以及执行它们所需的特权。
当前权限级别(CPL)保存在CS寄存器的某一位(技术上是x86上的2位)。
这是一个int指令所遵循的步骤:
•从IDT中获取第n个描述符,其中n是int的参数。
•检查%cs中的CPL是否<= DPL,其中DPL是描述符中的权限级别。
•如果没有,则用户没有足够的权限来执行此操作,并将导致执行int 13指令(一般性保护错误)(用户没有足够的权限)
•如果是,那么用户代码有足够的权限来执行这个系统调用,当前的执行上下文被保存(寄存器等),因为我们现在切换到内核模式。
这些信息包括寄存器,标志,因为当系统调用被屏蔽时,我们希望从我们离开的地方继续执行。 •系统调用的参数保存在内核堆栈中,因为系统调用是在内核模式下执行的。

VSYSCALL(快速系统呼叫)
每次系统调用都由用户执行时,Os会保存机器的当前状态(即寄存器,堆栈指针等)并切换到内核模式执行。 对于某些系统调用,不需要保存所有的寄存器。 Ex系统调用的获取时间读取当前时间,系统调用返回。 所以一些系统调用是通过叫做vsyscalls来实现的。 这里当系统调用被执行时,它在用户空间本身中执行,而不用切换到内核。 所以节省了时间。
有关vsyscall的详细信息,请参见此处http://www.trilithium.com/johan/2005/08/linux-gate/
在这里任何人都可以了解gettimeofday如何工作?

系统调用是由特殊的陷阱指令,系统调用号码和参数组成的。

  1. 特殊陷阱指令用于从用户模式切换到具有无限特权的内核模式。
  2. 系统调用号码和参数通过寄存器传递。