中国科学技术大学计算机系 陈香兰(0512- ) Spring 2011

Slides:



Advertisements
Similar presentations
2.5 函数的微分 一、问题的提出 二、微分的定义 三、可微的条件 四、微分的几何意义 五、微分的求法 六、小结.
Advertisements

7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
练一练: 在数轴上画出表示下列各数的点, 并指出这些点相互间的关系: -6 , 6 , -3 , 3 , -1.5, 1.5.
高级服务器设计和实现 1 —— 基础与进阶 余锋
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
Linux 系统. 操作系统发展需求 1 没有操作系统 2 简单批处理操作系统 3 多道程序设计的批处理 4 多道程序设计的分时操作系统 5 多处理机并行系统 6 网络操作系统 7 分布式操作系统.
孟宁 电话: 主页:
Oracle数据库 Oracle 子程序.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
中国科学技术大学计算机系 陈香兰(0512- ) Spring 2011
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
OpenMP简介和开发教程 广州创龙电子科技有限公司
强连通分量 无向图 1、任意两顶点连通称该图为连通图 2、否则将其中的极大连通子图称为连通分量 A D C B E 有向图
中国科学技术大学计算机系 陈香兰(0512- ) Autumn 2010
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
走进编程 程序的顺序结构(二).
辅导课程六.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
PostgreSQL 8.3 安装要点 四川大学计算机学院 段 磊
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
中国科学技术大学计算机系 陈香兰(0512- ) Autumn 2010
第十章 IDL访问数据库 10.1 数据库与数据库访问 1、数据库 数据库中数据的组织由低到高分为四级:字段、记录、表、数据库四种。
嵌入式操作系统 陈香兰 Spring 2008 中国科学技术大学计算机系.
中国科学技术大学计算机系 陈香兰(0512- ) Linux操作系统分析 中国科学技术大学计算机系 陈香兰(0512- )
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
逆向工程-汇编语言
如何生成设备节点 广州创龙电子科技有限公司
中国科学技术大学计算机系 陈香兰(0551- ) Spring 2009
中国科学技术大学计算机系 陈香兰(0512- ) Spring 2011
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
嵌入式操作系统 陈香兰 Spring 2008 中国科学技术大学计算机系.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
内容摘要 ■ 课程概述 ■ 教学安排 ■ 什么是操作系统? ■ 为什么学习操作系统? ■ 如何学习操作系统? ■ 操作系统实例
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
作业情况 已交作业人数:140人 凡是自己没有交过作业的同学,课后留下,有话要说。 2. 文件名范例: 姓名:王树武 wshw_1.c
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
第二章 Java基本语法 讲师:复凡.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月13日.
工业机器人知识要点解析 (ABB机器人) 主讲人:王老师
Lightweight Data-flow Analysis for Execution-driven Constraint Solving
1.2 有理数 第1课时 有理数 伏家营中学 付宝华.
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
信号量(Semaphore).
第4章 Excel电子表格制作软件 4.4 函数(一).
本节内容 内存复制指令 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
iSIGHT 基本培训 使用 Excel的栅栏问题
§6.7 子空间的直和 一、直和的定义 二、直和的判定 三、多个子空间的直和.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第4课时 绝对值.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
临界区问题的硬件指令解决方案 (Synchronization Hardware)
第15讲 特征值与特征向量的性质 主要内容:特征值与特征向量的性质.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
中国科学技术大学计算机系 陈香兰(0551- ) Spring 2009
Python 环境搭建 基于Anaconda和VSCode.
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
本节内容 通用寄存器 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
_08文件操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
作業系統 第十六章 系統服務常式.
第十七讲 密码执行(1).
Lab2 系统调用
多个Activity的使用 本讲大纲: 1、使用Bundle在Activity之间交换数据 2、调用另一个Activity并返回结果
Presentation transcript:

中国科学技术大学计算机系 陈香兰(0512-87161312) xlanchen@ustc.edu.cn Spring 2011 Linux操作系统分析 中国科学技术大学计算机系 陈香兰(0512-87161312) xlanchen@ustc.edu.cn Spring 2011

系统调用

系统调用的意义 操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用 把用户从底层的硬件编程中解放出来 极大的提高了系统的安全性 使用户程序具有可移植性 2018/11/23 Linux OS Analysis

API和系统调用 应用编程接口(application program interface, API) 和系统调用是不同的 系统调用通过软中断向内核发出一个明确的请求 Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用) 一般每个系统调用对应一个封装例程 库再用这些封装例程定义出给用户的API 2018/11/23 Linux OS Analysis

不是每个API都对应一个特定的系统调用。 如,一些数学函数 一个单独的API可能调用几个系统调用 不同的API可能调用了同一个系统调用 返回值 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用 -1在多数情况下表示内核不能满足进程的请求 Libc中定义的errno变量包含特定的出错码 2018/11/23 Linux OS Analysis

系统调用程序及服务例程 当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。 在Linux中是通过执行int $0x80来执行系统调用的, 这条汇编指令产生向量为128的编程异常 (回忆,trapinit中系统调用入口的初始化) Intel Pentium II中引入了sysenter指令(快速系统调用),2.6已经支持(本课程不考虑这个) 传参: 内核实现了很多不同的系统调用, 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数 使用eax寄存器 2018/11/23 Linux OS Analysis

所有的系统调用返回一个整数值。 这里的返回值与封装例程返回值的约定不同 正数或0表示系统调用成功结束 负数表示一个出错条件 内核没有设置或使用errno变量 封装例程在系统调用返回取得返回值之后设置这个变量 当系统调用出错时,返回的那个负值将要存放在errno变量中返回给应用程序 2018/11/23 Linux OS Analysis

系统调用处理程序也和其他异常处理程序的结构类似 在进程的内核态堆栈中保存大多数寄存器的内容 (即保存恢复进程到用户态执行所需要的上下文) 调用相应的系统调用服务例程处理系统调用 sys_xxx 通过ret_from_sys_call()从系统调用返回 2018/11/23 Linux OS Analysis

应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系 syscall_exit: 2018/11/23 Linux OS Analysis

为了把系统调用号与相应的服务例程关联起来,内核利用了一个系统调用分派表(dispatch table)。 这个表存放在sys_call_table数组中,有若干个表项(2.6.26中,是326): 第n个表项对应了系统调用号为n的服务例程的入口地址的指针 观察sys_call_table(syscall_table_32.S以及entry_32.S最后) 2018/11/23 Linux OS Analysis

关于系统调用表的大小 2018/11/23 Linux OS Analysis

初始化系统调用总入口 内核初始化期间调用trap_init()函数建立IDT表中向量128对应的表项,语句如下: 该调用把下列值存入这个系统门描述符的相应字段: segment selector 内核代码段__KERNEL_CS的段选择符 Offset 指向system_call()异常处理程序的入口地址 Type 置为15。表示这个异常是一个陷阱,相应的处理程序不禁止可屏蔽中断 DPL(描述符特权级) 置为3。这就允许用户态进程访问这个门,即在用户程序中使用int $0x80是合法的 2018/11/23 Linux OS Analysis

system_call()函数 参见entry_32.S 2018/11/23 Linux OS Analysis

参数传递 系统调用也需要输入输出参数,例如 实际的值 用户态进程地址空间的变量的地址 甚至是包含指向用户态函数的指针的数据结构的地址 system_call是linux中所有系统调用的入口点,每个系统 调用至少有一个参数,即由eax传递的系统调用号 一个应用程序调用fork()封装例程,那么在执行int $0x80之前就 把eax寄存器的值置为2(即__NR_fork)。 这个寄存器的设置是libc库中的封装例程进行的,因此用户一般 不关心系统调用号 进入sys_call之后,立即将eax的值压入内核堆栈 对C库进行反汇编,察看int $0x80 2018/11/23 Linux OS Analysis

很多系统调用需要不止一个参数 普通C函数的参数传递是通过把参数值写入堆栈(用户态堆栈或内核态堆栈)来实现的。但因为系统调用是一种特殊函数,它由用户态进入了内核态,所以既不能使用用户态的堆栈也不能直接使用内核态堆栈 用户态C函数 用户态堆栈 内核态C函数 内核态堆栈 2018/11/23 Linux OS Analysis

在int $0x80汇编指令之前,系统调用的参数被写入CPU的寄存器。然后,在进入内核态调用系统调用服务例程之前,内核再把存放在CPU寄存器中的参数拷贝到内核态堆栈中。因为毕竟服务例程是C函数,它还是要到堆栈中去寻找参数的 用户态C函数 用户态堆栈 内核态C函数 内核态堆栈 寄存器 SAVE_ALL 2018/11/23 Linux OS Analysis

回想一下在进入中断和异常处理程序前,在内核态堆栈中保存的pt_regs结构,此时pt_regs结构中的一些寄存器被用来传递参数或者pt_regs结构本身就是参数 2018/11/23 Linux OS Analysis

参数传递举例 处理write系统调用的sys_write服务例程声明如下 该函数期望在栈顶找到fd,buf和count参数 在封装sys_write()的封装例程中,将会在ebx、ecx和edx 寄存器中分别填入这些参数的值,然后在进入system_call时, SAVE_ALL会把这些寄存器保存在堆栈中,进入sys_write服务 例程后,就可以在相应的位置找到这些参数 asmlinkage使得编译器不通过寄存器(x=0)而 使用堆栈传递参数 Include/asm-x86/linkage.h 参见SAVE_ALL 2018/11/23 Linux OS Analysis

反汇编/lib/libc.so.6(可能是其他版本号) 197897 000bed90 <__write>: 197898 bed90: 65 83 3d 0c 00 00 00 cmpl $0x0,%gs:0xc 197899 bed97: 00 197900 bed98: 75 1d jne bedb7 <__write+0x27> 197901 bed9a: 53 push %ebx 197902 bed9b: 8b 54 24 10 mov 0x10(%esp),%edx 197903 bed9f: 8b 4c 24 0c mov 0xc(%esp),%ecx 197904 beda3: 8b 5c 24 08 mov 0x8(%esp),%ebx 197905 beda7: b8 04 00 00 00 mov $0x4,%eax 197906 bedac: cd 80 int $0x80 197907 bedae: 5b pop %ebx 197908 bedaf: 3d 01 f0 ff ff cmp $0xfffff001,%eax 197909 bedb4: 73 2d jae bede3 <__write+0x53> 197910 bedb6: c3 ret ………… 反汇编/lib/libc.so.6(可能是其他版本号) 2018/11/23 Linux OS Analysis

1)每个参数的长度不能超过寄存器的长度 ,即32位 由此,使用寄存器传递参数具有如下限制 : 1)每个参数的长度不能超过寄存器的长度 ,即32位 2)在系统调用号(eax)之外,参数的个数 不能超过6个(ebx,ecx,edx,esi,edi, ebp) ?超过6个怎么办? 2018/11/23 Linux OS Analysis

传递返回值 服务例程的返回值是将会被写入eax寄存器中 这个是在执行“return”指令时,由编译器自动完 成的 2018/11/23 Linux OS Analysis

验证参数 在内核打算满足用户的请求之前,必须仔细的检查所有的 系统调用参数 比如前面的write()系统调用,fd参数是一个文件描述符, sys_write()必须检查这个fd是否确实是以前已打开文件的一个 文件描述符,进程是否有向fd指向的文件的写权限,如果有 条件不成立,那这个处理程序必须返回一个负数 2018/11/23 Linux OS Analysis

只要一个参数指定的是地址,那么内核必须检查它是否在 这个进程的地址空间之内,有两种验证方法: 验证这个线性地址是否属于进程的地址空间 仅仅验证这个线性地址小于PAGE_OFFSET 对于第一种方法: 费时 大多数情况下,不必要 对于第二种方法: 高效 可以在后续的执行过程中,很自然的捕获到出错的情况 从linux2.2开始执行第二种检查 2018/11/23 Linux OS Analysis

要防止用户将一个内核地址作为参数传递给内核 ,这将导致它借用内核代码来读写任意内存 对用户地址参数的粗略验证 在内核中,可以访问到所有的内存 要防止用户将一个内核地址作为参数传递给内核 ,这将导致它借用内核代码来读写任意内存 2018/11/23 Linux OS Analysis

2018/11/23 Linux OS Analysis

检查方法: 最高地址:addr+size-1 1、是否超出3G边界 2、是否超出当前进程的地址边界 对于用户进程:不大于3G 2018/11/23 Linux OS Analysis

访问进程的地址空间 系统调用服务例程需要非常频繁的读写进程地址空 间的数据 2018/11/23 Linux OS Analysis

访问进程地址空间时的缺页 内核对进程传递的地址参数只进行粗略的检查 访问进程地址空间时的缺页,可以有多种情况 合理的缺页:来自虚存技术 页框不存在或者写时复制 由于错误引起的缺页 由于非法引起的缺页 2018/11/23 Linux OS Analysis

非法缺页的判定 内核中,只有少数几个函数/宏会访问用户地址空间 对于一次非法缺页,一定来自于这些函数/宏 可以将访问用户地址空间的指令的地址一一列举出 来,当发生非法缺页时,根据引起出错的指令地址 来定位 Linux使用了异常表的概念 __ex_table, __start___ex_table, __stop___ex_table 2018/11/23 Linux OS Analysis

__ex_table的表项 哪条指令访问了用户地址空间 如果这条指令引起了非法缺页,该怎么处理 Fixup所指向的代码,称为修正代码 通常为汇编代码 2018/11/23 Linux OS Analysis

fixup_exception 2018/11/23 Linux OS Analysis

缺页异常对非法缺页的处理 在缺页异常do_page_fault中,若最后发现是非法缺页,就会执行下面的操作 假设找到了修正代码,会发生什么事情? 该操作使用引起出错的代码地址在异常表中进行查找,若找到,就返回 相应的修正代码地址,填写在regs->eip中 2018/11/23 Linux OS Analysis

缺页处理 某内核函数 IDT表, 进入异 常处理 缺页 非法异常 修改堆栈中的eip,指向修正代码 因此,非法缺页时,返回此处 作为一次故障,要重新执行引起出错的代码 修正代码 正常情况下,这个eip在发生异常时, 由硬件保存到堆栈中 因此,正常情况下,返回此处 2018/11/23 Linux OS Analysis

异常表的生成和修正代码 2018/11/23 Linux OS Analysis

举例 2018/11/23 Linux OS Analysis

系统调用的返回 参见中断中的返回 2018/11/23 Linux OS Analysis

中断、异常、系统调用小结 ret_from_fork ret_from_exception iret ret_from_intr syscall_exit iret 内核态 用户态 IDT表 中断 异常 系统调用 2018/11/23 Linux OS Analysis

Project 参见课程主页 2018/11/23 Linux OS Analysis