6_syscall x86.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
6_syscall x86

xlanchen@2007.9.29 Linux内核源代码导读 Linux内核源代码导读 中国科学技术大学计算机系 陈香兰(0551-3606864) xlanchen@ustc.edu.cn Spring 2009 一个典型的Linux操作系统的结构 系统调用的意义 操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用 把用户从底层的硬件编程中解放出来 极大的提高了系统的安全性 使用户程序具有可移植性 API和系统调用 应用编程接口(application program interface, API) 和系统调用是不同的 API只是一个函数定义 系统调用通过“软”中断向内核发出一个明确的请求 在x86中为int指令 Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用) 一般每个系统调用对应一个封装例程 库再用这些封装例程定义出给用户的API 不是每个API都对应一个特定的系统调用。 API可能直接提供用户态的服务 如,一些数学函数 一个单独的API可能调用几个系统调用 不同的API可能调用了同一个系统调用 返回值 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用 -1在多数情况下表示内核不能满足进程的请求 Libc中定义的errno变量包含特定的出错码 系统调用程序及服务例程 当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。 在Linux中是通过执行int $0x80来执行系统调用的, 这条汇编指令产生向量为128的编程异常 (回忆,trap_init中系统调用入口的初始化) 传参: 内核实现了很多不同的系统调用, 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数 使用eax寄存器 系统调用的返回值 所有的系统调用返回一个整数值。 正数或0表示系统调用成功结束 负数表示一个出错条件 这里的返回值与封装例程返回值的约定不同 内核没有设置或使用errno变量 封装例程在系统调用返回取得返回值之后设置errno 当系统调用出错时,返回的那个负值将要存放在errno变量中返回给应用程序 系统调用处理程序也和其他异常处理程序的结构类似 在进程的内核态堆栈中保存大多数寄存器的内容 (即保存恢复进程到用户态执行所需要的上下文) 调用相应的系统调用服务例程处理系统调用 sys_xxx 通过syscall_exit从系统调用返回 应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系 为了把系统调用号与相应的服务例程关联起来,内核利用了一个系统调用分派表(dispatch table)。 这个表存放在sys_call_table数组中, 有nr_syscalls个表项:第n个表项对应了系统调用号为n的服务例程的入口地址的指针 观察sys_call_table 观察nr_syscalls的定义 初始化系统调用 内核初始化期间调用trap_init()函数建立IDT表中向量128对应的表项,语句如下: 其中,SYSCALL_VECTOR被定义为0x80 该调用把下列值存入这个系统门描述符的相应字段: segment selector:内核代码段__KERNEL_CS的段选择符 offset:指向system_call()异常处理程序的入口地址 type:置为15。表示这个异常是一个陷阱,相应的处理程序不禁止可屏蔽中断 DPL(描述符特权级):置为3。这就允许用户态进程访问这个门,即在用户程序中使用int $0x80是合法的 CPU执行int 0x80指令 过程类似中断 在进入system_call 之前,堆栈情况为 system_call()函数 观察SAVE_ALL 宏SAVE_ALL 在堆栈上依次保存了3个段寄存器fs、es、ds的值,以及ax、bp、di、si、dx、cx、bx这7个寄存器的值。 并对段寄存器ds、es、fs赋予适当的值 系统调用的参数传递 系统调用也需要输入输出参数,例如 实际的值 用户态进程地址空间的变量的地址 甚至是包含指向用户态函数的指针的数据结构的地址 system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号 例如: 一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)。 这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号 很多系统调用需要不止一个参数 普通C函数的参数传递是通过把参数值写入堆栈(用户态堆栈或内核态堆栈)来实现的。但因为系统调用是一种特殊函数,它由用户态进入了内核态,所以既不能使用用户态的堆栈也不能

文档评论(0)

dt80055 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档