2010 第5章 Linux系统调用.ppt

  1. 1、本文档共42页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
2010 第5章 Linux系统调用

第5章 Linux系统调用 系统调用功能概述 系统调用的处理过程 系统调用的实例分析 如何增加一个系统调用 系统调用概述 系统调用(SYSTEM CALL) OS内核中都有一组实现系统功能的过程,系统调用就是对上述过程的调用。编程人员利用系统调用,向OS提出服务请求,由OS代为完成。 一般情况下,进程是不能够存取系统内核的。它不能存取内核使用的内存段,也不能调用内核函数,CPU的硬件结构保证了这一点。只有系统调用是一个例外。 5.1 Linux系统调用-功能 系统调用是用户态进入内核态的唯一入口:一夫当关,万夫莫开。常用系统调用: 控制硬件:如write/read调用。 设置系统状态或读取内核数据——getpid()、getpriority()、setpriority()、sethostname() 进程管理:如 fork()、clone()、execve()、exit()等 优点 编程容易,从硬件设备的低级编程中解脱出来 提高了系统的安全性,可以先检查请求的正确性 5.1 Linux系统调用-功能 5.2 Int 0x80指令 Linux中实现系统调用利用了i386体系结构中的软件中断。即调用了int $0x80汇编指令。 这条汇编指令将产生向量为128的编程异常,CPU便被切换到内核态执行内核函数,转到了系统调用处理程序的入口:system_call()。 int $0x80指令将用户态的执行模式转变为内核态,并将控制权交给系统调用过程的起点system_call()处理函数。 system_call()函数 system_cal()检查系统调用号,该号码告诉内核进程请求哪种服务。 内核进程查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。 接着调用相应的函数,在返回后做一些系统检查,最后返回到进程。 系统调用和普通函数调用 API是用于某种特定目的的函数,供应用程序调用,而系统调用供应用程序直接进入系统内核。 Linux内核提供了一些C语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。 有的API函数在用户空间就可以完成工作,如一些用于数学计算的函数,因此不需要使用系统调用。 有的API函数可能会进行多次系统调用。 不同的API 函数也可能会有相同的系统调用。比如malloc(),calloc(),free()等函数都使用相同的方法分配和释放内存。 系统命令、内核函数 系统调用与系统命令 系统命令相对API来说,更高一层。每个系统命令都是一个执行程序,如ls命令等。这些命令的实现调用了系统调用。 系统调用与内核函数 系统调用是用户进入内核的接口层,它本身并非内核函数,但是它由内核函数实现。 进入内核后,不同的系统调用会找到各自对应的内核函数,这些内核函数被称为系统调用的“服务例程”。如系统调用getpid实际调用的服务例程为sys_getpid(),或者说系统调用getpid()是服务例程sys_getpid()的封装例程。 封装例程(wrapper routine) 由于陷入指令是一条特殊指令,依赖操作系统实现的平台,如在i386体系结构中,这条指令是int $0x80(陷入指令),不是用户在编程时应该使用的语句,因为这将使得用户程序难于移植。 在标准C库函数中,为每个系统调用设置了一个封装例程,当一个用户程序执行了一个系统调用时,就会调用到C函数库中的相对应的封装例程。 system_call()函数(见教材P234页) 首先将系统调用号(eax)和可以用到的所有CPU寄存器保存到相应的堆栈中(由SAVE_ALL完成); 对用户态进程传递过来的系统调用号进行有效性检查(eax是系统调用号,它应该小于 NR_syscalls) 如果是合法的系统调用,再进一步检测该系统调用是否正被跟踪; 根据eax中的系统调用号调用相应的服务例程。 服务例程结束后,从eax寄存器获得它的返回值,并把这个返回值存放在堆栈中,让其位于用户态eax寄存器曾存放的位置。 然后跳转到ret_from_sys_call(),终止系统调用程序的执行。 SAVE_ALL宏定义 #define SAVE_ALL cld; pushl %es; pushl %ds; pushl %eax; pushl %ebp; pushl %edi; pushl %esi; pushl %edx; pushl %ecx; pushl %ebx; movl $(__KERNEL_DS),%edx; movl %edx,%ds; movl %edx,%es;?? 系统调用表与调用号 这样系统调用处理程序一旦运行,就可以

文档评论(0)

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

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

1亿VIP精品文档

相关文档