---恢复内容开始---

第五章 系统调用

一、与内核通信

1.系统调用在用户控件进程和硬件设备之间添加了一个中间层。

为用户空间提供了一种硬件的抽象接口
系统调用保证了系统的稳定和安全
每个进程都运行在虚拟系统中,而在用户控件和系统的其余部分提供这样一层公共接口

2.作用

在Linux中,系统调用是用户空间访问内核的唯一手段 。

二、API、POSIX和C库

Linux的系统调用作为C库的一部分提供。
C库:Unix系统的主要API,包括标准C库函数和系统调用接口,即POSIXdM大部分API。

Unix的接口设计——“提供机制而不是策略”

三、系统调用

要访问系统调用,通常通过C库中的定义函数进行。

通常定义1个,零个,或2个参数,可能有一些副作用。

例:

通过返回一个long型的返回值来表示成功或者错误(写某个文件或者给指定的指针拷贝数据)
用一个负的返回值来表明错误,返回0代表成功。
系统调用出现错误的时候会把错误码写入errno全局变量
通过perror()库函数可以把该变量翻译成用户可以理解的错误字符串
比如: SYSCALL_DEFINE0 只是一个宏,定义一个无参数的函数调用。
展开后的代码如下 asmlinkage long sys_getpid(void)。

定义系统调用:

asmlinkage long sys_getpid(void)

asmlgkage:编译指令,通知编译器仅从栈中提取该函数的参数。所有的系统调用都需要这个限定词。

返回值long:为了保证32和64位系统的兼容,系统调用在用户空间返回值int,内核空间long

命名规则:sys_xxx

a. 系统调用号

每个系统调用被赋予一个系统调用号,系统调用发生时,内核就是根据传入的系统调用号来知道是哪个系统调用的。

在x86架构中,用户空间将系统调用号是放在eax中。

每个系统调用号独一无二,一旦分配就不能再有任何变更。
执行系统调用时,通过系统调用号指明,进程不会提及系统调用的名称。

内核记录了系统调用表中的所有已经注册过的系统调用列表,存储在sys_call_table中。

未实现系统调用——sys_ni_syscall(),返回-ENOSYS,针对无用的系统调用。

b.系统调用的性能——执行速度快

  • 上下文切换时间短。设计原则:简洁、高效
  • 系统调用处理程序和每个系统调用本身都很简洁

四、系统调用处理程序

1. 通知内核

用户程序无法直接执行内核代码,需要切换内核态,由于内核驻留在受保护的地址空间上,不能直接调用内核空间中的函数。
应用程序以某种方式通知系统,告诉内核自己需要执行一个系统调用,希望系统切换到内核态,需要切换内核态,这个通知内核的机制是软中断。
通知内核的机制是靠软中断实现的:通过引发异常来粗来系统切换内核态执行异常处理程序(系统调用处理程序)。
一个异常来促使系统切换到内核态中去执行异常处理程序,即系统调用处理程序system_call()。

2.指定恰当的系统调用

  • ax寄存器:将系统调用号传递给内核
  • system_call():与NR_syscall比较,检查有效性
  • call *sys_call_table(,%rax,8):执行相应的系统调用

3.参数调用

  • x86系统,ebx,ecx,edx,esi,edi按顺序存放前五个参数。
  • 需要6个及以上参数,应用一个单独的寄存器存放指向这些参数在用户空间地址的指针。
  • 返回值存放在eax。

system_call()函数通过将给定的系统调用号与NR_syscalls作比较来检查其有效性。

五、系统调用的实现

1.实现系统调用

 a .决定它的用途   不提倡采用多用途的系统调用

 b.原则:用途明确、简洁稳定、通用、可移植、健壮。

2.参数验证

必须检查每个参数,保证他们不但合法有效,而且正确:   不应让内核访问无权访问的资源.
最重要——检查用户提供的指针:

指针指向的内存区域必须属于用户空间指向的内存区域属于用户空间;
指针指向的内存区域在进程的地址空间内;
决不能绕过内存访问限制;指向的内存区在内存的访问权限范围中。

  

1.检查读写
(1)向用户空间写入数据——copy_to_user()
(2)从用户控件读取数据——copy_from_user()

针对是否有合法权限的检查

capable():是否有权对指定的资源进行操作

返回0:无权操作

以上两个函数成功返回0,失败返回没能完成拷贝的数据的字节数。
这两个函数都有可能引起阻塞——当包含用户数据的页被换出到硬盘上而不是物理内存上的时候。

 

六、系统调用上下文

内核在执行系统调用时处于进程上下文。

在进程上下文中,内核可以:

休眠:说明系统调用可以使用内核提供的绝大部分功能

被抢占:要求保证该系统调用是可重入的

current指针指向当前任务。

当系统调用返回时,控制权仍然在system_call()中,负责切换到用户空间,并让用户进程继续执行下去。

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

在系统调用表的最后加入一个表项。
对于所支持的各种体系结构,系统调用号都必须定义于<asm/unistd.h>中
系统调用必须被编译进内核映像,不能被编译成模块。

  

2.从用户空间访问系统调用

Linux本身提供了一组宏,如:_syscalln()。用于直接对系统调用进行访问。

_syscalln()    

n的范围从0到6,代表需要传递给系统调用的参数个数。

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

系统调用的返回值类型
系统调用的名称
按照系统调用参数的顺序排列每个参数的类型和名称。

  

3.提倡不通过系统调用的方式实现

建立一个系统调用的好处:

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

问题:

占用系统调用号
固化,不允许改动接口
需要分别注册到每个需要支持的体系结构中
脚本中不易调用,文件系统中也不能直接访问
在主内核树外难以维护使用

替代:

某些接口,例如信号量,用文件描述符表示
把增加的信息作为一个文件放在sysfs的合适位置。

七、 学习心得

看书的过程中,当时觉得理解,一旦应用到实践中,就会有混淆不理解的地方,还是在看书的过程中需要多理解问题。

 
 
 

Linux 第五章 学习笔记的更多相关文章

  1. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

  2. 《Linux内核设计与实现》第五章学习笔记

    <Linux内核设计与实现>第五章学习笔记 姓名:王玮怡  学号:20135116 一.与内核通信     在Linux中,系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核 ...

  3. Spring实战第五章学习笔记————构建Spring Web应用程序

    Spring实战第五章学习笔记----构建Spring Web应用程序 Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现,它能够构建像Spring框架那 ...

  4. 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记

    第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...

  5. 《Linux内核设计与实现》 第五章学习笔记

    第五章 系统调用 在现代操作系统中,内核提供了进程与内核进行交互的一组接口.有如下作用: 让应用程序受限的访问硬件设备 提供了创新进程并与已有进程进行通信的机制 提供了申请操作系统其它资源的能力 保证 ...

  6. 安卓权威编程指南 - 第五章学习笔记(两个Activity)

    学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 ...

  7. 20135320赵瀚青LINUX第五章读书笔记

    第五章--系统调用 5.1 与内核通信 作用 1.为用户空间提供一种硬件的抽象接口 2.保证系统稳定和安全 3.除异常和陷入,是内核唯一的合法入口. API.POSIX和C库 关于Unix接口设计:提 ...

  8. 2013337朱荟潼 Linux第五章读书笔记——系统调用

    摘要: [20135337朱荟潼]原创作品转载请注明出处 第五章 系统调用 5.1 与内核通信 中间层 作用三个:1.为用户空间提供一种硬件的抽象接口:2.保证系统稳定和安全:3.除异常和陷入,是内核 ...

  9. linux第三章学习笔记

    第三章 进程管理 进程是Unix操作系统抽象概念中最基本的一种. 进程管理是所有操作系统的心脏所在. 一.进程 1. 进程是处于执行期的程序.除了可执行程序代码,还包括打开的文件.挂起的信号.内核内部 ...

随机推荐

  1. 粗略的整改一下blog

    一.先找个简约的模板:看个人喜好咯 二.页面定制CSS: 1.首先,查看主页源码,了解一下各个标签的id,引用的class等 2.通过操作相应的id,class,和标签,进行个性化.这里需要具备看懂和 ...

  2. Alpha冲刺报告(7/12)(麻瓜制造者)

    今日已完成 邓弘立: 对主页UI进行了改进 符天愉: 打算开始写留言部分并且想要实现无限回复 搜索了下网上的实现方法,总结了两种方法,一种使用递归,一种使用嵌套集合.发现嵌套集合的方法很机智,,但是感 ...

  3. 树莓派3B+ wifi 5G连接

    新烧的Raspbian 系统,一开始需要设置wifi的一些配置,其中会选择一个国家(set country),一开始选择的是CN(中国),发现只能连接2.4G的网络,5G的网络连接不上,这很奇怪, 因 ...

  4. Test传送门(更新中)

    一.Codeforces传送门: Avito Code Challenge 2018 题解传送门 Codeforces Round #485 (Div. 2)     题解传送门 二.hihocode ...

  5. linux添加磁盘空间

    首先你要关掉系统,把分配的硬盘空间变大,或者重新建立一个虚拟硬盘(这时下面的就不是sda了,而是sdb1了).这两种方法都可行,我都试过了.其次用root用户登录到你的linux系统,查看你系统的分区 ...

  6. js_script

    使用 self.crawl 的 js_script 参数,在页面上执行一段脚本,实现[点击加载更多]的效果: def on_start(self): self.crawl('http://movie. ...

  7. C++之构造函数拷贝

    拷贝构造函数,顾名思义,就是通过拷贝对象的方式创建一个新对象.拷贝构造函数有两种原型(我们继续以book类来说明拷贝构造函数原型): book(book &b); book(const boo ...

  8. scp 免密登录ssh-copy-id 如何使用非22端口 + rsync 同步远程机器的文件到本地

    其中:id_rsa为私钥文件,id_rsa.pub为公钥文件 ssh-copy-id  -i ~/.ssh/id_rsa.pub  "-p 2122  root@IP " 我的:s ...

  9. DQN(Deep Reiforcement Learning) 发展历程(五)

    目录 值函数的近似 DQN Nature DQN DDQN Prioritized Replay DQN Dueling DQN 参考 DQN发展历程(一) DQN发展历程(二) DQN发展历程(三) ...

  10. MVC 全局拦截aciton

    上篇:MVC 拦截指定的action 有时,我们需要对所有aciton在执行前/后做一些(预)处理,如何实现呢? 1.定义一个action筛选类.继承至System.Web.Mvc.IActionFi ...