系统调用原理及详细过程

为什么要有系统调用?

由于系统的有限资源可能被多个不同的应用程序访问,因此,如果不加以保护,那么用程序难免产生冲突。所以,现代操作系统都将可能产生冲突的系统资源给保护起来,阻止应用程序直接访问。这些系统资源包括文件、网络、IO、各种设备等。

为了让应用程序有能力访问系统资源,也为了让应用程序能够借助操作系统做一些必须由操作系统支持的行为。每个操作系统都会提供一套接口,以供应用程序使用。这些接口往往通过中断来实现。

系统调用与运行库(标准库)

系统调用的弊端

  1. 使用不便。操作系统提供的系统个调用接口往往过于原始,程序员需要了解很多与操作系统相关的细节。如果没有很好的包装,使用起来不方便
  2. 各个操作系统之间的系统调用不兼容。首先Windows系统和Linux系统之间的系统调用就基本上完全不同。即使是同系列的操作系统的系统调用都不一样,比如Linux和Unix就不相同

为了解决这个问题,运行库作为系统调用与程序之间的一个抽象层挺身而出,它有一下特点:

  1. 使用简便。
  2. 形式统一。运行库有它的标准,叫做标准库,凡是所有遵循这个标准的运行库理论上都是相互兼容的,不会随着操作系统或编译器的变化而变化。

系统调用的原理:

现代操作系统通常让代码运行在两种不同特权的模式下
——用户态和内核态——以限制他们的权力。系统调用要操作一些有限的资源,无疑是运行在内核态的。那么用户态程序如何运行内核态的代码呢?操作系统一般是通过中断来从用户态切换到内核态。

中断

中断是指一个硬件或软件发出的请求(电信号),要求CPU暂停当前的工作转手去处理更加重要的事情。

中断一般有两个属性,中断号中断处理程序(ISR,Interrupt Service Routine)。在内核中,有一个数组称为中断向量表,包含了中断号及其对应中断处理程序的指针。中断到来时,CPU暂停当前执行的代码,根据中断的中断号,在中断向量表中找到对应的中断处理程序,并调用它。中断处理程序执行完成之后,CPU会继续执行之前的代码。

中断有两种类型:一种称为硬件中断,这种中断来自于硬件的异常或事件发生;另一种称为软件中断,软件中断通常是一条指令(i386下是int),带有一个参数记录中断号,使用这条指令用户可以手动触发某个中断并执行中断处理程序。

由于中断号是有限的,操作系统不舍得每一个系统调用对应一个中断号,而更倾向于用一个或少数几个中断号来对应所有的系统调用。Linux则使用int 0x80来触发所有系统调用。每个系统调用对应一份系统调用号,这个系统调用号在执行int 0x80指令前会放置在某个固定的寄存器里(eax),对应的中断代码会取得这个系统调用号,并且调用正确的函数。

系统调用的详细过程

1. 触发中断

用户程序在代码中调用系统调用,执行int指令前将系统调用号放入eax寄存器中,执行int 0x80指令
(int 指令最后执行的函数是system_call,该函数验证系统调用号的有效性,查找系统调用函数并执行,最后通过itret从中断处理程序返回)

2. 切换堆栈(此步在int指令中完成)

在实际执行0x80号中断向量所对应的中断处理程序(system_call)之前,CPU首先要进行堆栈切换,即从用户态切换到内核态。从中断处理函数中返回时,程序当前栈还要从内核栈切换回用户栈。

  • 所谓的当前栈,值得是esp(栈指针)的值所在的栈空间。如果esp的值位于用户栈的范围内,那么程序的当前栈就是用户栈,反之亦然。此外,寄存器ss的值还应该指向当前栈所在的页。
    所以,将当前栈由用户栈切换为内核栈的实际行为就是:
    (1) 保存当前的esp,ss的值(保证存在内核栈上,有int指令自动地由硬件完成)
    (2) 将esp,ss的值设置为内核栈的相应值
  • 当0x80号中断发生的时候,cpu除了切入内核态之外,还会自动完成下列几件事:
    (1)找到当前进程的内核栈(每一个进程都有自己的内核栈)
    (2)在内核栈中一次压入用户态的寄存器ss、esp、eflags、cs、eip
  • 而当内核从系统调用返回的时候,须要调用iret指令来回到用户态,iret指令则会从内核栈里弹出寄存器ss、esp、eflags、cs、eip的值,使得栈恢复到用户态的状态。

3. 中断处理程序

在int指令切换内核栈之后,程序就切换到了中断向量表中的0x80号中断处理程序。Linux中0x80向量对应的中断处理程序是system_call。

system_call中断服务程序首先检查系统调用号的有效性,再根据eax寄存器存储的系统调用号从系统调用表上找到相应的系统调用并调用。调用完成后从system_call中返回。以下是部分内核代码:

// system_call的开头部分
......
SAVE_ALL    // 保存寄存器的值到栈中,以免被覆盖
......
cmpl $(nr_syscalls), %eax   // 比较eax寄存器中的值和系统调用号大1的值(验证系统调用号的有效性)
jae syscall_badsys  // 如果系统调用无效,指向syscall_badsys// 如果系统调用号有效,则会执行以下代码
syscall_call:call *sys_call_table(0, %eax, 4)   // 查找中断服务程序并执行, sys_call_table其实就是系统调用表.....RESTORE_REGS // 恢复之前保存的寄存器......iret // 从中断程序返回

4. 从中断处理程序返回

在3中有描述

总结

用户运行库函数(系统调用的封装),函数里面其实是执行的int 0x80指令。系统调用先把系统调用号保存在eax寄存器中,然后执行int0x80指令。int 0x80指令先进行切换堆栈(找到进程的堆栈,将寄存器值压入到内核栈中,将esp,ss设置成对应内核栈的值),查找相应中断向量的中断处理程序(system_call)并调用,随后system_call 从系统调用表中找到相应的系统调用进行调用,调用结束后从system_call中返回。

参考文献

程序员的自我修养-链接、装载与库

系统调用原理及详细过程相关推荐

  1. 网站渗透测试原理及详细过程

    渗透测试实战 site:baidu.com 渗透测试思路 site:baidu.com 带你入门渗透测试的5个项目:https://www.jianshu.com/p/5b82e42ae346 渗透测 ...

  2. pxe网络安装操作系统 原理与详细过程

    1.操作系统安装的流程 通用流程:首先,bios启动,选择操作系统的启动(安装)模式(此时,内存是空白的),然后根据相关的安装模式,寻找操作系统的引导程序(不同的模式,对应不同的引导程序当然也对应着不 ...

  3. ARP中间人攻击详细过程及原理

    ARP中间人攻击详细过程及原理 一.实验详细过程 实验工具: Kali,ENSP,Wireshark 实验环境: Kali:IP: 192.168.135.1 Server:192.168.135.2 ...

  4. 老徐WEB:最简单详细的轮播图原理和制作过程(一)

    老徐利用空闲时间,制作了一个最简单的轮播图,主要介绍轮播图的原理和制作过程,只要大家能认真看完这篇文章,并理解文中内容,就能完全掌握轮播图的制作了.之后工作中碰到复杂的轮播图,自己也能思考制作出来了. ...

  5. DNS劫持详细过程及原理

    DNS劫持详细过程及原理 一.DNS劫持原理 1: DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求 2: 局域网劫持, 攻击者通过伪装成网关, 劫持受害者的网络请求, 将网络请求拦截 ...

  6. 电脑启动过程(超详细过程)

    Linux启动过程(超详细过程) 一.前言 二.启动过程概述 三.加电自检及初始化 四.主引导记录 五.加载kernel 六.加载init 致谢 一.前言 我开始的时候写了一篇关于Linux启动过程的 ...

  7. 深入分析Linux操作系统对于TCP/IP栈的实现原理与具体过程

    一.Linux内核与网络体系结构 在我们了解整个linux系统的网络体系结构之前,我们需要对整个网络体系调用,初始化和交互的位置,同时也是Linux操作系统中最为关键的一部分代码-------内核,有 ...

  8. Linux 系统调用原理

    了系统调用原理,或许能帮你找到进入kernel函数的入口. 一.Syscall意义 内核提供用户空间程序与内核空间进行交互的一套标准接口,这些接口让用户态程序能受限访问硬件设备,比如申请系统资源,操作 ...

  9. STM32F0xx_EXIT中断配置详细过程

    Ⅰ.概述 EXIT外部中断在使用到按键或者开关控制等应用中比较常见,低功耗中断唤醒也是很常见的一种.因此,EXIT在实际项目开发中也是比较常见的一种. STM32F0中外部中断EXIT属于中断和事件的 ...

最新文章

  1. 手把手教你在应用里用上iOS机器学习框架Core ML
  2. 在叠堆及虚拟化的今天生成树存在的理由
  3. 【鬼网络】之DHCP原理与配置
  4. C/C++ BugPitfalls
  5. 拥抱开放,Serverless 时代的下一征程
  6. php树形结构数组转化
  7. VS 2017 + EF6 + MySQL5.7 建立实体模型闪退问题
  8. 智慧环卫车辆监控管理系统方案
  9. Java程序员开发软件(工具)清单
  10. 《大学》全文及白话翻译
  11. Shell脚本 | 考勤统计
  12. 官方指南:小米手机微信双开
  13. uniapp 集成腾讯云超级播放器问题
  14. 固定效应还是随机效应?
  15. android画布橡皮,Android绘图实现橡皮擦功能
  16. Ubuntu20.04电脑开启热点
  17. 工业物联网的实际应用案例以及技术分析
  18. 苹果cms10好看的模板自适应高端大气免费模板
  19. js 绘画js 绘画路径_绘画是一种技能,而不是才能
  20. 概括几种项目类型使用的技术路线

热门文章

  1. 什么是WAF?有什么功能?
  2. 模糊的照片可以变清晰吗?
  3. 嵌入式之串口中断只能收到一个字节
  4. RAID磁盘阵列之RAID 6
  5. docker配置defects4j + SimFix
  6. python怎么转换文件格式_python怎么转换数据类型
  7. How to be better
  8. 单片机开发和嵌入式开发的区别
  9. 论文阅读Patient-specific reconstruction of volumetric computed tomography images from a single projectio
  10. getopt函数详解