Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52801
  • 博文数量: 65
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 14
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-08 16:56
文章分类
文章存档

2015年(65)

我的朋友

分类: LINUX

2015-11-08 21:09:00

     应用编程接口(API)与系统调用不同。前者只是一个函数定义,说明了如何获得一个给定的服务;而后者是通过软件中断向内核态发出一个明确的请求。一个API没必要对应一个特定的系统调用。
   首先,API可能直接提供用户太的服务(例如一些抽像的数据函数,根本没必要使用系统调用)。其次,一个单独的API函数可能调用几个系统调用。另外几个API函数可能调用封装了不同功能的同一系统调用。当用户态的进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。
   从编程者的观点看,API和系统调用之间的差别是没有关系的:唯一相关的事情就是函数、参数类型及返回代码的含义。然而,从内核设计者的观点看,这种差别确实有关系,因为系统调用属于内核,而用户太的库函数不属于内核。当用户态的进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。在80x86体系结构中,可以用两种不同的方式调用Linux的系统调用。两种方式的最终结果都是转到所谓系统调用处理程序(system call handler)的汇编语言函数中。因为内核实现了很多不同的系统调用,因此进程必须传递一个名为系统调用号(system call number)的参数来识别所需要的系统调用,eax寄存器就用作此目的。
   系统调用处理程序与其他异常处理程序的结构类似,执行下列操作:
(1)在内核态栈保存大多数寄存器的内容
(2)调用名为系统调用服务例程(system call service routine)的相应的C函数来处理系统调用
(3)退出系统调用处理程序:用保存在内核栈中的值加载寄存器,CPU从内核态切换回到用户态。
用户进程可以通过两种不同的方式调用系统调用:
(1)执行init $0x80汇编指令。在Linux内核的老版本中,这是从用户态切换到内核态的唯一方式。
(2)执行sysenter 汇编语言指令。在Intel Pentium 微处理器芯片中引入了这条指令。现在Linux2.6内核支持这条指令。
   同样,内核可以通过两种方式从系统调用退出,从而使CPU回到用户态:
执行iret汇编语言指令
执行sysexit汇编语言指令,它和sysenter指令同时在Intel Pentium 微处理器中引入。
 具体内容可以参考:《深入理解Linux内核》一书的第十章”系统调用“。
阅读(290) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~