当前位置: 首页 > news >正文

Linux 系统调用的来龙去脉 (上)

《linux系统调用的来龙去脉》分为上下两篇,本文为上篇。

1.前言

开始正题前先讲两个生活小案例来引出系统调用的意义。

案例一:图书馆

安居不用架高堂,书中自有黄金屋。娶妻莫恨无良媒,书中自有颜如玉。

图书馆是我喜欢去的一个地方,相信大家也都去过。在图书馆我们可以自由阅读任何书,广泛的汲取各种知识。正是由于所有人都可以自由的阅读任意书籍,所以经常就会出现书籍位置出现错乱,书籍页面出现损坏,甚至还会出现书籍遗失的情况。

实例二:收藏馆

价值连城的艺术品往往存放在特定温度和湿度的存储柜中,为了确保艺术品的安全,通常将它们存放到安全级别很高的收藏馆中。如果客户希望参观它们,先需要提交申请,进入收藏馆后,由专门的人员拿出艺术品供客户参观欣赏。这样保证了艺术品不受破坏,也保证了艺术品的安全。

根据上述两个例子得出以下结论:

如果每个用户都能自由使用“ 资源”,随着时间的推移,“ 资源”就会出现损坏。如果“ 资源”由“ 专业人员”管理,每个用户只能间接的使用“ 资源”,这样就可以安全的长久的使用“ 资源”。

2.如何保证系统安全性

操作系统提供给应用程序运行环境,让各种应用得以运行。 在应用程序运行过程中有些操作是非常危险的,如果每个应用程序都能自由进行任何操作,就有可能带来如下各种问题:

1、多个应用程序直接去操作硬件外设,就会出现相互冲突,可能会出现需要应用程序A的读取数据,被应用程序B读取的情况。

2、多个应用程序被加载到内存,应用程序A占用了一个内存区域Z,应用程序B自己强制清空内存区域Z,那么就给应用程序A带来致命问题。

3、部分应用程序需要硬件中断让自己在合适的时机开始执行,如果其它应用程序把中断关掉,那么这些依靠中断触发的应用程序将再也得不到执行。

在应用程序运行过程中有些危险的操作将会对其它应用程序造成伤害,甚至会对操作系统造成伤害,导致系统崩溃。如果所有应用程序都可以使用这些操作,那么整个系统将是不稳定的,不安全的。

如何防止应用程序对其它应用程序和操作系统造成伤害?

造成这种问题的原因是每个应用程序都可以自由的使用关键“资源”,这就类似上文提到的图书馆模式,每个人都可以自由阅读所有书籍,所以容易出现书籍损坏(影响其它人阅读)。

为了让应用程序都能正常运行不受其它应用程序伤害,为了系统能安全,稳定的长久运行,系统需要使用收藏馆模式。在收藏馆模式下关键“资源”由“专业人员”管理,每个应用程序只能间接的使用“资源”。

3.特权级

为了让系统系统能安全,稳定的长久运行,必须有一个有特权的“专业人员”对核心资源进行管理,那么就带来两个问题:

1、专业人员的特权是什么?

2、如何获取特权?

特权是啥?

计算机的硬件和软件是共同在发展,为了适应操作系统,处理器发展出两种权限模式: 用户模式和特权模式

以ARM V7 体系架构为例,为了提高稳定性,ARM V7 体系处理器有7种运行模式,每种运行模式的使用权限不一样,有六种特权模式和一种用户模式,如下图所示:

由图可知:FIQ,IRQ,SVC,ABT,UND,SYS这六种模式是特权模式,USR是用户模式。 在用户模式下有些指令是无法操作的,如进行MMU或cache的操作,在特权模式下任何指令都是可以操作的。

这就回答了第一个问题“专业人员的特权是什么”, “专业人员”可以使用处理的特权模式,这样“专业人员”就可以在处理器上进行任何操作。而应用程序则在用户模式下,只运行在处理器上进行部分操作。在ARM V7 体系架构种SVC模式是为“专业人员”提供的特权模式。

如何获取特权?

硬件中断是在电平变化时引发中断操作,而 软中断是通过一条具体指令SWI,当CPU执行到SWI指令时会触发中断,进入中断程序(中断模式是特权模式)。

以ARM V7 体系架构为例, 软件中断指令(SVC)用于产生软中断,实现从用户模式变换到特权模式。

SVC汇编指令如下:

SVC {cond} immed_24

//其中immed_24 24位立即数,值为从0~16777215之间的整数。

这就回答了第二个问题 “如何获取特权?”,使用软件中断指令进入中断,“专业人员”在中断模式下,中断模式也是特权模式。

总结: 为了让系统系统能安全,稳定运行,重要资源有“专业人员”操作,应用程序可以通过软中断指令“召唤”“专业人员”来完成相关操作。

4.内核态

在计算机软件系统中包含一个名为 操作系统的程序集合,在这个程序集合包括内核,设备驱动程序,启动引导程序,shell程序,文件管理工具等, 其中最重要的程序称为内核(kernel)。计算机的软件系统的模式和能力由内核决定,内核为操作系统中的所有事物提供了主要的功能,同时决定了上层应用软件的很多特性。

用户界面和应用程序是操作系统的外在表象, 内核才是操作系统的内在核心!系统的其它部分必须依赖内核这个程序。

通俗的描述就是: 内核是操作系统中最重要的一个程序!操作系统中的其它程序都依赖这个内核程序!

内核为何如此重要?内核在操作系统中完成了以下 两个重要功能

1、与计算机硬件交互。

2、为计算机系统中的应用程序提供执行环境。

内核可以被称作管理者,因此前文说到的“专业人员”就是指的内核。内核运行在计算机的特权模式下,这样使得内核有了“无所不能”的能力, 通常我们将运行在特权模式下的内核称为“内核态”,运行在用户模式的用户程序称为“用户态”。内核拥有特权,无所不能,系统的其它部分都依赖内核,操作系统中内核就是一个王者般的存在。

5.系统调用

为了保证操作系统的安全性,比如创建进程或者硬件交互这种操作不能由应用程序去完成,而必须让操作系统内核来完成。但是应用程序就有比如创建进程或者硬件交互这种操作需求,如何满足应用程序的需求?

系统调用提供了应用程序和操作系统之间的接口,应用程序通过系统调用实现其与操作系统的通信,并可取得操作系统的服务。

当应用程序中需要操作系统提供服务时,如创建进程或执行 I/O 操作,应用程序必须使用系统调用。处理器捕获到该命令后,便将处理器的状态从用户态转换为内核态(特权模式),然后操作系统在特权模式下执行相应的程序,执行完成后,系统又将处理器状态从内核态转换到用户态,继续执行应用程序。

系统调用是应用程序请求操作系统内核完成某功能的一种过程调用,它与一般的过程调用的最大差别:

1.状态不同。一般的过程调用其调用程序和被调用程序运行在相同的状态,而系统调用是调用程序是运行在用户态,而被调用程序是运行在内核态态。

2.状态转换。由于系统调用的调用和被调用过程工作在不同的系统状态,因而不能由调用过程直接转向被调用过程,需要通过软中断机制。用户态触发中断,处理器产生中断,系统切换到内核态(特权态),经操作系统内核根据传入的调用号,执行相应的系统调用处理程序。

系统调用本质上是应用程序请求操作系统内核完成某功能时的一种过程调用。通俗的说法就是遇到事情叫大哥出马!

6.系统调用模型

由于linux系统调用比较复杂,因此我们先讲述系统调用的模型,然后再讲述linux的系统调用实现。

系统调用的本质是: 应用程序请求操作系统内核完成某个功能

我们根据系统调用的本质,将系统调用分解成如下 三板斧

第一板斧:系统调用请求

应用程序可以根据自身需求自由调用系统请求,应用程序传递参数给系统调用请求函数,在系统调用请求函数内部,通过指令触发软中断。以ARM V7A 体系架构为例,软件使用SVC指令产生软中断。

第二板斧:处理器响应请求进入特权模式

由于在系统调用请求函数内部执行软中断指令,此时处理器暂停当前用户程序,进入软中断函数,此时处理器进入特权模式,在中断函数中完成一些准备工作后,执行功能函数。

第三板斧:在特权模式下内核完成某个功能

一个特定功能的函数被软中断函数调用,执行功能函数期间处理器处于特权模式下。

系统调用的三板斧模型如下

根据系统调用模型,用C语言实现一个简单的系统调用,C语言代码实例如下:

实现的3个函数功能如下:

request函数是一个调用接口函数,实现软中断触发功能。

irq_handler函数为软中断响应函数,该函数主要是完成调用功能函数。

function函数为在内核态实现的特定功能。

C语言实现的系统调用的基本模型的调用流程如下:

上述这个简单的系统调用, 实现了一个具体功能为function函数的系统调用,并且这个系统调用只有一个功能函数, 实现了从零到一的过程

接下来增加难度, 不是只实现1个具体功能,而是要实现10个功能,如何实现?

有 两种策略可以实现多个功能的系统调用:

策略1:使用多个软中断,每个软中断函数执行一个功能函数。

策略2:使用一个软中断,在软中断函数中根据传入的参数,执行不同的功能函数。

对比上述两种策略:

策略1使用多个软中断,这种模式每个软中断对应一个功能函数,这样 系统响应速度会快一些,但是劣势非常明显,系统调用的数量直接受处理器硬件影响, 系统移植性较差

策略2使用一个软中断,这种方式在触发软中断时向软中断函数传入一个调用号,在中断中函数中根据调用号执行指定的功能函数,由于多进行了一些操作,系统响应速度会慢一点,但是优势也非常明显,系统调用的个数几乎不受限制,对处理器硬件要求低, 系统移植性强

Linux系统调用就是使用的策略2,综上所述系统调用可以拆分为以下 3个基本要素

1、调用请求,传入参数和调用号,触发软中断。

2、响应请求,进入中断函数,根据调用号执行指定的功能函数

3、功能实现,在内核态下实现特定功能。

未完待续…

作者:liyinuo2017

- EOF -

点击标题可跳转

1、 探索 OS 的内存管理原理

2、 80% 的 Linux 都不懂的内存问题

3、 Linux 动态链接过程中的【重定位】底层原理

相关文章:

  • Elasticsearch 查询时 判断不为null或不为空字符串
  • BP神经网络需要训练的参数,BP神经网络图像识别
  • 10.导弹拦截
  • docker 上mysql通过Navicat访问
  • C#学生成绩查询(使用方法实现,查最大值,最小值,平均值,升序,降序)
  • k8s---特殊操作(修改hostname)
  • KubeClipper——轻量便捷的 Kubernetes 多集群全生命周期管理工具
  • (分布式缓存)Redis分片集群
  • 线性DP问题
  • ORA-28000: the account is locked
  • LeetCode220902_93、搜索二维矩阵 II
  • SpringBoot关闭Tomcat容器,SpringBoot使用Jetty容器
  • 记录angular使用codemirror的过程和遇到的问题
  • 猿创征文|当我在追光 我与光同航--我与Java的技术成长之路
  • python基础专栏12-python基础篇-复合数据类型-字典
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 2017年终总结、随想
  • 3.7、@ResponseBody 和 @RestController
  • Android框架之Volley
  • CSS实用技巧干货
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JavaScript 一些 DOM 的知识点
  • JAVA多线程机制解析-volatilesynchronized
  • JAVA之继承和多态
  • maven工程打包jar以及java jar命令的classpath使用
  • python3 使用 asyncio 代替线程
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 编写高质量JavaScript代码之并发
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 前端路由实现-history
  • 算法之不定期更新(一)(2018-04-12)
  • 探索 JS 中的模块化
  • 突破自己的技术思维
  • 微信小程序填坑清单
  • 终端用户监控:真实用户监控还是模拟监控?
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • #1015 : KMP算法
  • #ubuntu# #git# repository git config --global --add safe.directory
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转) 深度模型优化性能 调参
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)visual stdio 书签功能介绍
  • (转)程序员技术练级攻略
  • (转载)Google Chrome调试JS
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .mysql secret在哪_MySQL如何使用索引
  • .net中调用windows performance记录性能信息
  • ::
  • [<死锁专题>]
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林