谈谈linux系统调用

  系统调用:由操作系统实现的所有系统调用所构成的集合即程序接口或应用编程接口(Application Programming Interface,API),是应用程序同系统之间的接口。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。

  系统调用接口的主要任务是把进程从用户态切换到内核态。在具有保护机制的计算机系 统中,用户必须通过软件中断或陷阱,才能使进程从用户态切换为内核态。 在i386体系中,Linux的系统调用接口是通过调用软中断指令“int  0x80”使进程从用户态进入内核态的,这个过程也叫做“陷入”。当系统调用接口调用软中断指令“int  0x80”时,这个指令会发生一个中断向量码为128的中断请求,并在中断响应过程中将进程由用户态切换为内核态。

  因为Linux只允许系统调用接口使用128这一个软中断向量,这也就意味着所有的系统调用接口必须共享这一个中断通道,并在同一个中断服务例程中调用不同的内核服务例程,所以,系统调用接口除了要引发“int 0x80”软中断之外,为了进人内核后能调用不同的内核服务例程,还要提供识别内核服务例程的参数,这个参数叫做“系统调用号”。也就是说,所有可为进程提供服务的内核服务例程都应具有一个唯一的系统调用号。

  几个概念:

  (1)系统调用号:用来标识一个系统调用用的,每个系统调用服务例程都有一个唯一的系统调用号;

  (2)系统调用表(sys_call_table):系统调用号与内核服务函数的对照表,根据系统调用号就可以找到相应的内核服务函数;

  系统调用过程:

    

  简单来说:系统调用的过程概括为:整个系统调用的过程可以总结如下:
  1. 执行用户程序foo()
  2.调用系统调用foo(), 在foo()中调用“int 0x80”软中断陷入内核,此时把系统调用号传递到eax寄存器中,若有其他的函数参数,则传递到ebx,ecx,edx,esi,edi寄存器中。

  3. 进入内核态后,首先先通过系统调用号在系统调用表中查询系统调用服务函数

    system_call()函数通过将给定地 系统调用号来进行有效性检查,若不在范围内则返回错误,否则进行相应的系统调用:

      call *sys_call_table(,%eax,4)

      因为系统调用表的表项是32位的,座椅通过系统调用号*4,就能得到表中查询的位置即:系统调用例程的地址;

  4.在进行真正的系统调用服务函数之前还必须检查参数的正确性

      检查参数,力求合法有效还要正确实在检查指针的时候,要保证:

        指针指向的内存区域属于用户空间,进程不能哄骗内核去读内核空间的数据

        指针指向的内存区域在进程的地址空间中,进程决不能哄骗内核去读其他进程的数据

        如果是读,该内存应该 被标记为可读,写得话标记为可写,不能绕过访问权限的限制。

  5.检查完毕,进入系统调用例程,进行执行,执行完毕,返回相应的返回值

 

测试一下网站变更时间

 

posted @ 2013-10-16 15:17  学会淡定  阅读(366)  评论(0编辑  收藏  举报