第五章 系统调用

5.1 与内核通信

1.调用在用户空间进程和硬件设备之间添加了一个中间层。该层主要作用有三个:

  • 为用户空间提供了硬件的抽象接口。
  • 系统调用保证了系统的稳定和安全。
  • 实现多任务和虚拟内存,保证良好的稳定性和安全性。

2.系统调用是用户空间访问内核的唯一手段;除异常和陷入外,是内核唯一合法的入口。

5.2 API、POSIX和C库

1.情况下,应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程。

2.C库提供了POSIX的绝大部分API。

5.3 系统调用

1.要访问系统调用(syscall),通常通过C库中定义的函数调用来进行。

2.如何定义系统调用,注意:

  • asmlinkage为限定词,是一个编译指令,通知编译器仅从栈中提取该函数的参数。
  • 函数返回long。
  • 系统调用get_pid()在内核中被定义为sys_getpid()。

5.3.1系统调用号

1.在Linux系统中,每个系统调用被赋予一个系统调用号,这样通过这个第一无二的号就可以关联系统调用。当用户空间的进程执行一个系统调用时,系统调用号用来指明执行哪个系统调用;进程不会提及系统调用的名称。

2.系统调用号一旦分配就不会再有任何变更,否则编译好的应用程序就会崩溃。如果一个系统调用被删除,所占用的系统调用号也不许被回收利用。sys _ ni _ syscall()专门针对无效的系统调用而设立的,只返回-ENOSYS。

3.内核记录了系统调用表中的所有已注册的系统调用的列表,存储在sys_call_table中。在x86-64中,他被定义于3arch/i386/kernel/syscall_64.c文件中,为每一个有效的系统调用指定唯一的系统调用号。

5.3.2系统调用的的性能

1.很短的上下文切换时间

2.系统调用处理程序和每个系统调用本身都很简洁。

5.4 系统调用处理程序

5.4.1指定恰当的系统调用

1.在X86中,系统调用号通过eax寄存器传递给内核,system _ call()函数通过将给定的系统调用与NR _syscalls作比较来检查其有效性,如果大于或等于NR _syscalls就返回-ENOSYS,否则就执行相应的系统调用:

call *sys_call_table(,%eax,8)//基址+偏移量*8

5.5系统调用的实现

5.5.1 实现系统调用

  • 他要做些什么
  • 新系统调用的参数、返回值和错误码又该是什么?
  • 系统调用设计的越通用越好
  • 时刻注意可移植性和健壮性

5.5.2参数验证

1.系统调用必须仔细检查所有的参数是否合法有效,而且必须是正确的。

2.最重要的一种检查是检查用户提供的指针是否有效,在接收一个用户空间的指针之前,内核必须保证:

  • 指针所指向的内存区域属于用户空间。
  • 指针所指向的内存区域在进程的地址空间之内。
  • 如果是读,该内存应被标记为可读,如果是写,该内存应被标记为可写,如果是可执行,该内存应被标记为可执行。进程决不能绕过内存访问限制。

3.内核提供了两个方法来完成必须的检查内核空间与用户空间数据的来回拷贝。

  • 为了向用户空间写数据,内核提供了copy _ to _user(),它需要三个参数,第一个是进程空间中的目的内存地址,第二个是内核空间内的源地址,第三个是需要拷贝的数据长度(字节数)。

  • 为了从用户空间读数据,内核提供了copy _ from _user(),该函数把第二个参数指定位置上的数据拷贝到第一个参数的指定位置,第三个是需要拷贝的数据长度(字节数)。

如果运行成功,则返回0,如果失败,则返回没能拷贝成功的字节数。

4.检查针对是否有合法权限

调用capable()函数检查用户是否有权对指定资源进行操作,返回非0值则有权限,返回0无权限。

<linux/capability.h>中包含一份所有权能和其对应的权限列表。

5.6 系统调用上下文

1.内核在执行系统调用时处于进程上下文。在进程上下文中,内核可以:

  • 休眠:说明系统调用可以使用内核提供的绝大部分功能。
  • 可以被抢占:要求保证该系统调用是可重入的。

5.6.1 绑定一个系统调用的最后步骤

  1. 在系统调用表的最后加入一个表项。
  2. 对于所支持的各种体系结构,系统调用号都必须定义于<asm/unistd.h>中。
  3. 系统调用必须被编译进内核映像(不能被编译成模块)。只要将其放进kernel/下的一个相关文件中即可,例如sys.c,它包含了各种各样的系统调用。

5.6.2 从用户空间访问系统调用

1.通常,系统调用靠C库支持。

2.Linux本身提供了一组宏,用于直接对系统调用进行访问。他会设置好寄存器并调用陷入指令。

3.对于每个宏来说,都有(2+2xn)个参数:

  • 第一个参数是系统调用的返回值类型
  • 第二个参数是系统调用的名称
  • 再以后是按照系统调用参数的顺序排列每个参数的类型和名称。
  • _ NR _open在<asm/unistd.h>中定义,是系统调用号。这个宏会被扩展成为内嵌汇编的C函数。

5.6.3 为什么不通过系统调用的方式实现

好处:

  • 系统调用创建容易并且使用方便
  • linux系统调用的高性能

问题:

  • 你需要―个系统调用号,而这需要一个内核在处于开发版本的时候由官方分配给你
  • 系统调用被加入稳定内核后就被固化了,它的接口不允许做改动
  • 需要将系统调用分别注册到每个需要支持的体系结构中去
  • 在脚本中不容易调用系统调用,也不能从文件系统直接访问系统调用
  • 由于你需要系统调用号,因此在主内核树之外是很难维护和使用系统调用的

替代方法:

实现一个设备节点,并对此实现read()和write()。使用特定的信息进行检索。

  • 像信号量这样的某些接口,可以用文件描述符来表示,因此也就可以按上述方式对其进行操作
  • 把增加的信息作为一个文件放在sysfs的合适位置

Linux内核分析 读书笔记 (第五章)的更多相关文章

  1. Linux内核分析 读书笔记 (第一章、第二章)

    第一章 Linux内核简介 1.1 Unix的历史 Unix很简洁,仅仅提供几百个系统调用并且有一个非常明确的设计目的. 在Unix中,所有东西都被当做文件,这种抽象使对数据和对设备的操作是通过一套相 ...

  2. 20135239 益西拉姆 linux内核分析 读书笔记之第四章

    chapter 4 进程调度 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 多任务系统可以划分为两类: - 非抢占式多任务: - 进程会一直执行直到自己主动停止运行(这一 ...

  3. Linux内核分析 读书笔记 (第三章)

    第三章 进程管理 3.1 进程 1.进程: 进程就是处于执行期的程序. 进程就是正在执行的程序代码的实时结果. 进程是处于执行期的程序以及相关的资源的总称. 进程包括代码段和其他资源. 2.线程:执行 ...

  4. Linux内核分析 读书笔记 (第四章)

    第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有通过调度程序的合理调度,系统资源才能最大限 ...

  5. Linux内核分析 读书笔记 (第七章)

    第七章 链接 1.链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或被拷贝)到存储器并执行. 2.链接可以执行于编译时,也就是在源代码被翻译成机器代码时:也可以执行于 ...

  6. Linux内核分析 读书笔记 (第十八章)

    第十八章 调试 18.1 准备开始 1. 需要的只是: 一个bug 一个藏匿bug的内核版本 相关内核代码的知识和运气 2. 在跟踪bug的时候,掌握的信息越多越好. 18.2 内核中的bug 1.  ...

  7. 《Linux内核设计与实现》第四周读书笔记——第五章

    <Linux内核设计与实现>第四周读书笔记--第五章 20135301张忻 估算学习时间:共1.5小时 读书:1.0 代码:0 作业:0 博客:0.5 实际学习时间:共2.0小时 读书:1 ...

  8. 《Linux内核设计与实现》读书笔记——第五章

    <Linux内核设计与实现>读书笔记--第五章 标签(空格分隔): 20135321余佳源 第五章 系统调用 操作系统中,内核提供了用户进程与内核进行交互的一组接口.这些接口让应用程序受限 ...

  9. Linux内核分析课程笔记(一)

    linux内核分析课程笔记(一) 冯诺依曼体系结构 冯诺依曼体系结构实际上就是存储程序计算机. 从两个层面来讲: 从硬件的角度来看,冯诺依曼体系结构逻辑上可以抽象成CPU和内存,通过总线相连.CPU上 ...

随机推荐

  1. 2.2Python数据处理篇之---math模块的数学函数

    目录 目录 前言 (一)一览表 1.基本函数 2.对数函数 3.三角函数 4.角度的切换 5.双曲函数 6.math定义的常数 (二)实例 目录 前言 math模块是基础的python数学函数模块,是 ...

  2. 10LaTeX学习系列之---Latex的文档结构

    目录 目录 前言 (一)对于Ctex宏包中的文档结构 1.说明 2.源代码 3.输出效果 4.技巧 (二)对于ctexart的文档结构 1.说明 2.源代码 3.输出效果 (三)对于ctexbook的 ...

  3. January 15th, 2018 Week 03rd Monday

    We got things to do. Places to go. People to see. Futures to make. 我们有很多事情要做,有很多地方要去,有很多人要见,有很多美好的未来 ...

  4. 团队项目管理:Github项目误删恢复记录

    参考: 准备更换git托管,如何迁移原git仓库 Github项目误删恢复记录 今天正常上线打卡,发现组织的线上Github仓库被误删了..本来是一场悲剧,所幸在本地的垃圾箱中翻出了还没有删除的本地仓 ...

  5. Android Studio入门问题汇总

    1.如何设置 AS 中的字体大小 2.如何切换 AS 的皮肤颜色,默认为黑色,修改为白色,改为 default 3.首次安装 Android Studio并打开时,如果创建了一个新工程并将工程保存在另 ...

  6. 点击事件click和onclick的区别

    一句话:$(selector).click()事件只能绑定静态元素.$(selector).on('click',function(){ })支持动态绑定元素. 如果是动态生成的元素,绑定事件只能用o ...

  7. vs2015添加管理员权限

    在工作过程中,我可能可能遇到要求编译好的程序默认以管理员权限运行,我们可以这样操作 一.新建一个manifest文件: <?xml version="1.0" encodin ...

  8. android Application Component研究之Activity(二)

    http://blog.csdn.net/windskier/article/details/7172710 本文为原创文章,欢迎转载!转载时请注明出处:http://blog.csdn.net/wi ...

  9. centos7下安装docker(5镜像命名)

    1.前面我制作了很镜像,利用docker images可以看到我自己制作的所有的镜像 第一列  是我利用docker build -t 镜像名   制作镜像指定的镜像名,但是它对应的是REPOSITO ...

  10. Dubbo高级篇4

    https://blog.csdn.net/moonpure/article/details/52842115 线程模型 http://dubbo.io/User+Guide-zh.htm 用户指南& ...