linux内核分析学习笔记 ——第四章 系统调用的三层机制

学习重点——系统调用


用户态、内核态和中断

  • Intel x86 CPU有四种不同的执行级别,分别是0,1,2,3其中数字越小,特权越高。

    • Linux操作系统只采用了其中的0和3两个特权级别,分别对应内核态和用户态。

      • 内核态:对应高执行级别,代码可以执行特权指令,访问任意物理内存,CPU执行级别对应的内核态。
        内核态的CS:EIP指向范围是任意地址
      • 用户态:对应底执行级别,代码能够掌控的范围会受到限制。
        用户态时,以32位x86机器为例,4G的进程地址空间只能访问0x000000~0xbfffffff的地址空间。
    • 每个进程都有一个4G大小的虚拟地址空间,在这个4G大小的虚拟地址空间中,前0~3G为用户空间,每个进程的用户空间之间是相互独立的,互不相干。

以下图示表示x86 32位机器的进程内存

  • 中断

    • 进入内核态一般是由终端触发的,以下时进入内核态的两种情况

      • 硬件中断,在用户进程执行时,硬件中断信号到来进入内核态,就会执行这个中断对应的中断服务历程。
      • 用户态程序执行过程中,调用了一个系统中断,陷入内核态(Trap)。系统调用就是一种特殊的中断
    • 从用户态到内核态的寄存器上下文的切换
      • 从用户态切换到内核态,将用户态寄存器的上下文保存起来,同时将内核态寄存器的值放入当前CPU中。
      • int指令触发中断机制
        • 会在内核栈内保存一些寄存器的值

          • 包括 用户态栈顶地址%esp 当前状态字 当前CS:EIP的值
          • 同时会将内核态的栈顶地址、内核态状态字放入CPU对应的寄存器中。CS:EIP指向中断处理程序的入口,对于系统来讲就是system_call
    • 中断处理的过程

      Linux系统调用通过中断向量0x80实现 int 0x80 ,中断保存了用户态CS:EIP的值,及当前堆栈段寄存器的栈顶(注意在这里的栈顶是用户栈的栈顶,入栈到内核栈),EFLAGS寄存器的当前值保存到内核堆栈。利用int指令将系统调用的中断服务程序的入口加载在CS:EIP中。

      • 完成中断服务程序,发生进程调度

        • 如果没有发生进程调度,直接恢复现场,iret回到原来的状态。
        • 如果发生了进程调度,当前这些状态暂时保存在内核堆栈中,下一次发生进程调度再切换回当前进程。

系统调用

概述

系统调用的意义是操作系统为用户态进程与硬件设备之间进行交互提供了一组接口。

操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境来使应用程序具有更好的兼容性,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序

  • 把用户从底层的硬件编程中解放出来
  • 极大的提高了系统的安全性
  • 使用户程序具有可移植性

系统调用的3层机制

系统调用的库函数就是我们使用的操作系统提供的API,系统调用是通过软中断向内核发出中断请求,int指令触发中断请求。

libc函数库内部定义的一些API内部就使用了系统调用的封装历程。

每个系统调用对应一个系统调用的封装例程,函数库再使用这些封装例程定义给出程序员可以调用的API一个API可能只对应一个系统调用,也可能由多个系统调用实现。

如上图所示,在用户态中

  • 用户态中的xyz()函数属于API函数
  • 该API中SYSTEMCALL就是一个系统调用的封装例程由操作系统给,出会触发int $0x80中断

在内核态中

  • 触发中断后进入内核态,system_call对应内核代码的起点,即中断向量0x80对应的终端服务程序的入口
  • 内核代码中的sys_xyz()系统调用处理函数
    • 处理结束后,如果发生进程调度会ret_from_sys_call
    • 如果没有发生进程调度,会执行iret返回用户态继续执行

触发系统调用及参数传递方式

  • 触发系统调用的方式

    • 当用户执行系统调用时,CPU切换到内核态执行system_call这是中断的入口函数也是内核代码的起点。
    • linux中使用0x80触发系统调用所对应的中断异常。
    • 内核通过给每个系统调用一个编号来区分,即系统调用号,实现将API函数xyz()和系统调用内核函数sys_xyz()
    • 用户进程必须指明需要哪一个系统调用,需要使用EAX寄存器
  • 参数传递的方式
    • 系统调用从用户态切换到内核态时使用的不同的堆栈,所以参数的传递无法通过参数压栈的方式进行传递。
    • 参数按照顺序赋值给EBX ECX EDX ESI EDI EBP 参数的个数不能超过6个寄存器。如果参数过多,就把寄存器作为指针指向内存,以传递更多的参数

实验:使用两种方法实现触发系统调用

使用库函数API触发系统调用

利用上面的代码实现的是查看当前进程的pid和其父进程的pid,首先是利用库函数提供的API实现查看。下面是运行结果。

使用内嵌汇编的方式实现系统调用

将上面的调用API转换成内嵌汇编代码的方式。通过查找可以看到对应的操作系统给出的系统调用的封装对应的系统调用号

下面对汇编代码解释其含义
movl $0,%%ebx\n\t表示传入参数,这里不需要传递参数,就将EBX寄存器清零
movl $0x14,%%eax\n\tEAX用于传递系统调用号,表示这里调用的是20号系统调用。
int $0x80\n\t是触发系统调用陷入内核执行20号系统调用的内核处理函数
movl %eax,%0\n\t系统调用会有一个返回值,通过EAX寄存器返回。
这样就完成了系统调用。

通用的触发系统调用函数

当libc没有提供某个系统调用的封装,可以利用libc提供的syscall函数直接调用

转载于:https://www.cnblogs.com/zz-1226/p/9922000.html

2018-2019-1 20189206 《Linux内核原理与分析》第五周作业相关推荐

  1. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  2. 2022-2023-1 20222809《Linux内核原理与分析》第一周作业

    Linux内核原理与分析第一周作业 配置环境 1.参考Linux(Ubuntu)系统安装图文教程中第二种借助virtualbox成功配置Ubuntu环境 2.升级更新软件包 可以通过调节分辨率和虚拟机 ...

  3. 实验楼 linux内核原理与分析,《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  4. 《Linux内核原理与分析》第二周作业

    反汇编一个简单的C程序 1.实验要求 使用: gcc –S –o test.s test.c -m32 命令编译成汇编代码,对汇编代码进行分析总结.其中test.c的具体内容如下: int g(int ...

  5. 2018-2019-1 20189218《Linux内核原理与分析》第九周作业

    进程调度的时机 进程调度时机就是内核调用schedule函数的时机.当内核即将返回用户空间时,内核会检查need_resched标志是否设置.如果设置,则调用schedule函数,此时是从中断(或者异 ...

  6. 2021-2022-1 20212820《Linux内核原理与分析》第一周作业

    声明:本文是基于Linux 基础入门_Linux - 蓝桥云课 (lanqiao.cn)这门课学习所写的课程笔记. 实验1 Linux系统简介 Linux主要包括是系统调用和内核两部分 Linux与W ...

  7. 20189220 余超《Linux内核原理与分析》第一周作业

    实验一 Linux系统简介 通过实验一主要是学习到了Linux 的历史简介,linux与windows之间的区别,主要是免费和收费,软件和支持,安全性,使用习惯,可制定性,应用范畴等.linux具有稳 ...

  8. 2018-2019-1 20189201 《LInux内核原理与分析》第九周作业

    那一天我二十一岁,在我一生的黄金时代.我有好多奢望.我想爱,想吃,还想在一瞬间变成天上半明半暗的云.那一年我二十一岁,在我一生的黄金时代.我有好多想法.我思索,想象,我不知该如何行动,我想知道一个城市 ...

  9. 2018-2019-1 20189208《Linux内核原理与分析》第九周作业

    活动 main函数编译有问题,div 函数和系统中某个函数重名,浮点输出有问题,scanf也有问题 修改如下 scanf_s("%d %d", &a, &b); p ...

  10. 2021-2022-1 20212808《Linux内核原理与分析》第一周作业

    一.实验中出现的问题 理解不清二进制数字表示和加减赋值表示文件权限.比如 chmod 600 test.txt 中600是如何计算的. chmod abc file chmod 600 text.tx ...

最新文章

  1. Silverlight 控件开发记录之 extern alias” 关键字
  2. leetcode算法题--最长公共前缀
  3. 有关session的登录注销的一个小例子
  4. Android笔记之ViewPager实现滑动页面
  5. UA MATH564 概率分布1 二项分布上
  6. boost::log::expressions::has_attr用法的测试程序
  7. [有限元] DistMesh Matlab 程序示例
  8. Linux系统挂载新硬盘
  9. Orcle数据库 表的 内置函数 内链接 外连接 相关练习题
  10. LaTeX 有哪些「新手须知」的内容?
  11. java论文word_java毕设论文参考文献.doc
  12. 吉他入门乐理知识精髓篇
  13. matlab实验报告井字棋,有偿井字棋游戏300+
  14. AQS(AbstractQueuedSynchronizer)同步器
  15. Linux运维之系统服务及远程服务器 SSH
  16. hrm项目-day02
  17. Qt编写安防视频监控系统57-子模块1设备列表
  18. 2021年低压电工考试题及低压电工模拟考试题
  19. git-bash.exe和git-cmd.exe运行Git的区别
  20. 解决ESlint验证

热门文章

  1. PhotoZoom的工具栏 图片放大不失真
  2. 上海老大杜月笙——教你看穿一个人
  3. Visual Studio 和 .NET Framework 词汇表(vs2008)
  4. 如何在Excel中根据数量生成抽奖名单
  5. 你们听歌都是用什么软件听?这里有三款优秀的小众音乐播放器!
  6. 神奇!一张图测试你是用左脑还是右脑! (含控制方法揭秘)
  7. win10升级工具_Win7倒计时34天!微软最后一次免费升级至win10,你敢来吗?
  8. Microsoft Office 2010安装教程
  9. 关于CH340T 的一点记录
  10. 测试CH340G有无工作