第10节系统调用.ppt

  1. 1、本文档共125页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第10章系统调用 本章对Linux系统调用的定义、基本原理、使用方法和注意事项作了概括的介绍,以便读者对Linux系统调用建立一个大致的印象。较详细地讨论了系统调用wait、waitpid和exec函数族,并通过两个实际例子来说明系统调用。 10.1 系统调用概述 所有的操作系统都提供多种服务的入口点,由此程序向内核请求服务。各种版本的Unix都提供经良好定义的有限数目的入口点,经过这些入口点进入内核,这些入口点被称为系统调用(system call)。系统调用是不能更改的一种Unix特征。 10.1.1 系统调用过程 Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。二者在使用方式上也有相似之处。 随Linux核心还提供了一些C语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。 在Linux中,系统调用的过程大体如图10.1所示: 一般来说,CPU硬件决定了进程不能访问内核所占内存空间也不能调用内核函数,这被称作保护模式。系统调用是这些规则的一个例外。系统调用的原理是:进程先用适当的值填充寄存器,然后调用一个特殊的指令跳转一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。硬件知道一旦跳到这个位置,就不是在限制模式下运行的用户,而是作为操作系统的内核。在Intel CPU中,这个指令由中断0x80实现。 进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,该号码告诉内核进程请求哪种服务。然后内核进程查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着调用相应的函数,在返回后做一些系统检查,最后返回到进程(如果这个进程时间用尽,则返回到其他进程)。sysem_call的代码在源码/kernel/entry.s中Entry(system_call)的下一行。 实际上,很多已经被习以为常的C语言标准函数,在Linux平台上的实现都是靠系统调用完成的,所以如果想对系统底层的原理作深入的了解,掌握各种系统调用是初步的要求。Linux下编程高手,其标志之一也是能对各种系统调用有透彻的了解。 在很多情况下,系统调用是实现编程想法的简洁有效的途径,所以应该尽量多掌握一些系统调用,这会对程序设计过程带来意想不到的帮助。 10.1.2 系统调用的进入 系统调用的进入可分为“用户程序调用系统调用总控程序(system_call)”和“系统调用总控程序调用各个服务程序”两部分;下面将分别对这两个部分进行详细说明: (1)“用户程序调用系统调用总控程序”的实现:Linux的系统调用使用第0x80号中断向量项作为总的入口,即系统调用总控程序的入口地址system_call就挂在中断0x80上。也就是说,只要用户程序执行0x80中断 ( int 0x80 ),就可实现“用户程序 系统调用总控程序”的进入。只是0x80中断的执行语句int 0x80 被封装在标准C库中,用户程序只需用标准系统调用函数就可以了,而不需要在用户程序中直接写0x80中断的执行语句int 0x80。中断的进入的详细过程可参见第3章“中断和中断处理”。 (2在系统调用总控程序中,通过语句“call * SYMBOL_NAME(sys_call_table)(,%eax,4)”来调用各个服务程序(SYMBOL_NAME是定义在/include/linux/linkage.h中的宏:#define SYMBOL_NAME_LABEL(X) X),可以忽略)。当系统调用总控程序执行到此语句时,eax中的内容即是相应系统调用的编号,此编号即相应服务程序在系统调用向量表sys_call_table中的编号(系统调用的编号的有关说明在/linux/include/asm/unistd.h中)。又因为系统调用向量表sys_call_table每项占4个字节,所以由%eax 乘上4形成偏移地址,而sys_call_table则为基址;基址加上偏移所指向的内容就是相应系统调用服务程序的入口地址。所以此call语句就相当于直接调用对应的系统调用服务程序。 在Linux中所有系统调用服务例程都使用了asmlinkage标志。此标志是一个定义在/include/linux/linkage.h 中的一个宏: #if defined __i386__ (__GNUC__ 2 || __GNUC_MINO

您可能关注的文档

文档评论(0)

kehan123 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档