日期:2014-05-16  浏览次数:20793 次

Linux内核探讨-- 第三章

文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处:

                                                                              http://blog.csdn.net/dlutbrucezhang/article/details/12207851

      第三章 --系统调用

      系统调用就是指当前的用户进程处于进程上下文中,由内核执行函数负责执行。是用户进程和内核交互的一组接口。提供这些接口的目的是使得用户进程可以和硬件设备通信。
      普通的用户进程是不能直接和硬件通信的,这是出于保护的目的,当然,也是为了方便用户的操作。毕竟硬件是和体系结构相关的。

1.与内核通信

      在很多时候,用户需要与内核通信,请求内核帮助当前进程完成一些操作。比如读文件和写文件的操作,进程不可能只是在用户空间中完成这些功能。
      现在举一个例子。我们需要写文件时会用到 write 函数,我们用到的函数其实是函数库中的库函数,其内部实现其实是系统调用。

2.系统调用状态

      通常,系统调用成功时,会返回 0 ,如果返回的是一个负数,那么基本可以认为,调用失败了。同时,为了让我们知道为什么会失败,C库会把一个错误码写入全局变量 errno 中。这个被称作是错误码。我们可以利用 perror() 函数查看出错原因。
      系统调用在内核中的实现是统一的形式:
      asmlinkage long sys_xxx(...);这里对这个形式不多做解释说明。

3.系统调用号

      在Linux中,每个系统调用都被赋予一个数值,这个数值被称为系统调用号。内核识别系统调用并不是通过系统调用的名称,而是通过这个数值。
      在内核中存储着一张系统调用表--sys_call_table ,内核根据这样的一一对应关系调用相关的函数。
      注意:即使是我们删除了一个系统调用,它的系统调用号仍然需要保留,因为当内核发现进程调用一个不存在的系统调用时,它会返回一个错误标识,但是,如果我们删除了那个系统调用号,有可能其他的系统调用会重复利用这个号,这样,我们产生的可是大错误啊。

4.系统调用处理程序

      用户空间的程序利用软中断进入内核,并由内核代替进程的执行,此时,进程处于进程上下文中。
      通知内核的机制是利用软中断实现的。在X86的架构中,软中断的中断号是128,表示为 int $0x80。这个处理程序的名字是 sys_call()。
      这个函数通过用户指定的系统调用号寻找合适的系统调用程序,并处理它。
      我们常常会传递一些参数给系统调用,这些参数是放在寄存器中的。当然,如果参数是很多个,那个就需要在寄存器中存储指向参数的内存地址了。

5.系统调用的实现

      由于这一部分的内容是固定的,都是需要按照一定的模式,所以,这里,对这一部分不多做介绍。