linux系统调用接口.ppt
《linux系统调用接口.ppt》由会员分享,可在线阅读,更多相关《linux系统调用接口.ppt(37页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 第第1010章章 系统调用接口系统调用接口系统调用接口的功能系统调用接口的功能内核内核为用用户与硬件与硬件设备(例如:例如:CPU,磁磁盘,打印机等,打印机等)交互提供了一个接口。交互提供了一个接口。该接口被称接口被称为系系统调用接口。用接口。它的功能是:它的功能是:v使用户编程更加容易,把用户从学习硬件使用户编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来。设备的低级编程特性中解放出来。v可以极大提高系统的安全性,因为内核接可以极大提高系统的安全性,因为内核接收用户请求之前,可以检查其合法性。收用户请求之前,可以检查其合法性。v使用系统调用接口使得程序具有良好的可使用系统调用接口
2、使得程序具有良好的可移植性。移植性。10.110.1 APIAPI和系和系统调用用UNIX操作系操作系统为编程程员提供了提供了应用用编程程接口接口(API)。在在API提供的提供的libc标准函数准函数库中,一部分中,一部分是用是用户态的的库函数,另一部分是系函数,另一部分是系统调用。用。库函数和系函数和系统调用的用的区区别是是:库函数是一个函数定义,说明如何获得一个给库函数是一个函数定义,说明如何获得一个给定的服务,库函数代码不属于内核。定的服务,库函数代码不属于内核。系统调用是通过软件中断系统调用是通过软件中断(int指令指令)向内核发向内核发出的一个明确服务请求,提供服务的代码属于出的一
3、个明确服务请求,提供服务的代码属于内核代码。内核代码。为了区了区别库函数和系函数和系统调用,用,libc标准准C库中,每个系中,每个系统调用都有一个封装例程用都有一个封装例程(wrapperroutine)。应用程序通用程序通过这个封装例程来引用个封装例程来引用API函数函数库中的系中的系统调用。用。用用户执行一个系行一个系统调用用时,内核通,内核通过(int0 x80)软件中断或件中断或调用用门从用从用户空空间进入内入内核空核空间,这就是所就是所谓的的模式模式转换。CPU切切换到内核到内核态开始开始执行与系行与系统调用相用相对应内核函数。内核函数。执行行结束后内核将束后内核将执行行结果和控制
4、果和控制权还给用用户进程。程。图10-6给出出调用系用系统调用的示意用的示意图。调用一个系用一个系统调用示意用示意图 printf()在应用程序中在应用程序中调用系统调用调用系统调用printf()int 0 x80 在在libclibc库中库中的封装例程的封装例程用户态用户态system_call:sys_printf()ret_from_sys_call iretsys_printf()内核态内核态系统调用处理系统调用处理机制机制系统调用服系统调用服务例程务例程图图10-6系统调用示意图系统调用示意图10.210.2 模式模式转换的硬件的硬件处理理在在i386中,完成系中,完成系统调用接口
5、模式用接口模式转换的的硬件是陷阱硬件是陷阱门和和调用用门,软件是件是int0 x80指令或指令或调用指令用指令下面分析陷阱门技术。下面分析陷阱门技术。注:调用门技术请读者见教材注:调用门技术请读者见教材P227(因因为通常情况下,在为通常情况下,在Linux内核没有使用调内核没有使用调用门)这里不做介绍。用门)这里不做介绍。陷阱陷阱门模式模式转换系系统调用属于用属于软件中断件中断。i386保保护模式下的模式下的软件中断件中断使用使用陷阱陷阱门描述描述符符。使用陷阱门执行软件中断,不会影响使用陷阱门执行软件中断,不会影响硬件中断请求。硬件中断请求。Linux为系统调用设置的陷阱门向量号是为系统调
6、用设置的陷阱门向量号是128,即,即16进制的进制的“80H”。i386使用的陷阱使用的陷阱(trap)指令是指令是int$0 x80。图图10-1给出陷阱门进行模式转换的示意图。给出陷阱门进行模式转换的示意图。系统调用的服务例程系统调用的服务例程 system_call()处理程序处理程序 中断描述符表中断描述符表 offset dpl 01111 selector offset GATE 0baseaddr limitdpl bseaddr baseaddr limit IDT的基址的基址 限长限长selector base addr limit中断描述符寄存器中断描述符寄存器IDTRCS
7、(代码段寄存器代码段寄存器)代码段描述符高速缓存代码段描述符高速缓存 system_call()起始地址起始地址 物理存储器物理存储器一个门描一个门描述符占述符占8B。在在GDT或或LDT中的中的代码段描代码段描述符。述符。陷阱门陷阱门 80H图图10-1陷阱门模式转换图陷阱门模式转换图10.310.3 系系统调用接口用接口i386保保护模式下,系模式下,系统调用接口由用接口由软件和件和硬件共同硬件共同协作完成。作完成。下面下面讲解系解系统调用用处理程序理程序system_call的工作原理。的工作原理。初始化系初始化系统调用用系系统启启动内核初始化期内核初始化期间调用用trap_init函函
8、数建立数建立IDT表中向量号表中向量号为128对应的表的表项(8个字个字节的陷阱的陷阱门描述符描述符)。代。代码如下:如下:set_system_gate(SYSCALL_VECTOR,&system_call);#defineSYSCALL_VECTOR0 x80上面两行代码等效于下面的语句:上面两行代码等效于下面的语句:set_system_gate(0 x80,&system_call);set_system_gate()初始化初始化80H开始的开始的8个字个字节的陷阱的陷阱门描述符。步描述符。步骤如下:如下:1.将内核代码段选择符将内核代码段选择符_KERNEL_CS装入装入80H陷阱
9、门的陷阱门的2、3两个字节。两个字节。2.将将system_call()可执行代码的第一条指令可执行代码的第一条指令偏移量装入偏移量装入80H陷阱门的陷阱门的0、1、6和和7共共4个字节中。个字节中。3.将将15添入添入80H陷阱门类型号字段,说明这陷阱门类型号字段,说明这是一个陷阱门。是一个陷阱门。4.将门描述符将门描述符DPL字段设置为字段设置为3,允许用户,允许用户进程调用进程调用system_call()程序。程序。10.3.2 10.3.2 系系统调用用执行流程行流程 在封装例程中含有在封装例程中含有int$0 x80汇编指令代码汇编指令代码 int$0 x80使该调用进入内核:使该
10、调用进入内核:system_call()该系统调用被执行,并返回执行结果该系统调用被执行,并返回执行结果 该系统调用由标准该系统调用由标准C库的封装例程(宏)来引导库的封装例程(宏)来引导 用户发出一个系统调用的请求用户发出一个系统调用的请求 由由system_call找到指定的系统调用函数找到指定的系统调用函数图图10-4 系统调用的执行流程系统调用的执行流程 封装例程封装例程system_call()是系是系统调用入口点。用入口点。系系统调用主要供用用主要供用户编程使用,但也可程使用,但也可以被内核以被内核态线程程调用。用。为了了简化系化系统调用的用的调用用过程,程,Linux提提供的封装
11、例程是一供的封装例程是一组预处理宏。共定理宏。共定义了了6个宏:个宏:v从从_syscall0到到_syscall5#define_syscallN(type,name,type1,arg1,type2,arg2,type3,arg3,.)typename(type1arg1,type2arg2,type3arg3,.)long_res;_asm_volatile(int$0 x80:=a(_res):0(_NR_#name),b(long)(arg1),c(long)(arg2),d(long)(arg3);._syscall_return(type,_res);程序清单程序清单10-1封装
12、例程:封装例程:程序清单程序清单10-1给出封装例程的定义给出封装例程的定义:封装例程的解封装例程的解释_syscallN中的中的“N”是系是系统调用的参数个用的参数个数。数。前两个字符串指明系统调用的前两个字符串指明系统调用的返回值类型和返回值类型和名字名字;紧随其后的每一对参数指明该系统调用所需紧随其后的每一对参数指明该系统调用所需要的其他参数的类型和名字。要的其他参数的类型和名字。fork()系统调用无参数,它的封装例程是:系统调用无参数,它的封装例程是:系统调用名字系统调用名字调用参数个调用参数个数数返回类型值返回类型值_syscall0(int,fork)write()系统调用有系统
13、调用有3个参数,其封装例程个参数,其封装例程宏指令格式是:宏指令格式是:可以按照程序清可以按照程序清单10-1把把_syscall3(int,write,)宏展开成下面的代宏展开成下面的代码:_syscall3(int,write,int,fd,constchar*,buf,unsignedint,count)参数个数参数个数其中,兰色字符串是其中,兰色字符串是write()系统调用需系统调用需要的要的3对参数。对参数。intwrite(intfd,constchar*buf,unsignedintcount)long_res;_asm_volatile(int$0 x80:=a(_res):
14、0(_NR_write),b(long)fd),c(long)buf),d(long)count);if(unsignedlong)_res=(unsignedlong)-125)errno=-_res;_res=-1;return(int)_res;它是系统调用号,来自它是系统调用号,来自_syscall3()的第的第2个参数个参数对这个函数个函数进行行编译,生成的,生成的汇编代代码如下:如下:write:pushl%ebx;将将ebx内容进栈内容进栈movl8(%esp),%ebx;将第一个参数放入将第一个参数放入ebxmovl12(%esp),%ecx;将第二个参数放入将第二个参数放入e
15、cxmovl16(%esp),%edx;将第三个参数放入将第三个参数放入edxmovl$4,%eax;将将_NR_write放入放入eaxint$0 x80;执行系统调用执行系统调用cmpl$-125,%eax;检测返回码检测返回码jbe.L1;如无错跳转如无错跳转negl%eax;求求eax的补码的补码movl%eax,errno;将结果放入将结果放入errnomovl$-1,%eax;将将eax置为置为-1.L1:popl%ebx;从堆栈弹出从堆栈弹出ebxret;返回调用程序返回调用程序从汇编代码中可知传递给从汇编代码中可知传递给write()的参数的参数是在执行是在执行int0 x80
16、指令之前就被装入到指令之前就被装入到CPU各个寄存器中。各个寄存器中。如果如果eax中的返回值为中的返回值为-1到到-125之间,将之间,将被解释为错误码。否则返回被解释为错误码。否则返回eax中的值,中的值,表明调用成功。表明调用成功。系系统调用号与系用号与系统调用表用表system_call()函数是内核中所有系函数是内核中所有系统调用用的唯一入口点,因此内核要的唯一入口点,因此内核要为每个系每个系统调用用编一个序号,一个序号,这个序号叫做个序号叫做系系统调用号。用号。从上一从上一节的封装例程代的封装例程代码中可以看到,中可以看到,执行行int0 x80之前,系之前,系统调用号已被放在用号
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 系统 调用 接口
限制150内