Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lab2 系统调用 2016-3-21.

Similar presentations


Presentation on theme: "Lab2 系统调用 2016-3-21."— Presentation transcript:

1 Lab2 系统调用

2 Lab1实验提交 总人数: 134 提交人数: 98 未提交(草稿): 23 未提交: 13 3月15日前提交者加分10%
未提交(草稿)减分10% 未提交只有10%

3 Lab1实验提交 提交后无法更改? 要有信心 学会慎重 后悔药? 没有! 网站规定

4 Lab1实验问题 perl 脚本可执行权限问题 GDB调试断点 chmod +x utils/genboot.pl
右击 properties, is excutable GDB调试断点 编译选项 –ggdb file filename break function

5 目录 实验内容 IA-32中断机制 系统调用 加载用户程序 实现库函数

6 实验内容

7 实验内容 内核: 建立完整的系统调用机制, 实现系统 调用putc 库: 基于putc系统调用实现库函数printf(格式 化输出)

8 实验内容 从实模式进入保护模式 加载内核到内存某地址并跳转运行 初始化中断向量表 初始化 GDT 表 配置 TSS 段
进入用户空间前的相关配置 正式进入用户空间 调用库函数 printf

9 IA-32中断机制

10 IA-32中断机制 内核的一个主要功能就是处理硬件外设I/O 处理器速度一般比外设快很多
内核必须处理其他任务,只有当外设真正完成了准备 好了时CPU才转过来处理外设IO IO方式: 轮询、中断、DMA等 轮询方式效率不高 中断机制就是满足上述条件的一种解决办法

11 IA-32中断机制 中断(广义)会改变处理器执行指令的顺序,通 常与CPU芯片内部或外部硬件电路产生的电信号 相对应
中断——异步的: 由硬件随机产生,在程序执行的任何时候可能出现 异常——同步的: 在(特殊的或出错的)指令执行时由CPU控制单元产 生 Exception在i386中与trap是一个意思,但中文翻译的 时候往往翻译成异常或陷阱,其实也是一个意思

12 中断 中断分为: 可屏蔽中断(Maskable interrupt) 非屏蔽中断(Nonmaskable interrupt)
I/O设备发出的所有中断请求(IRQ)都可以产生可屏蔽 中断。 可屏蔽中断可以处于两种状态:屏蔽的(masked)和非 屏蔽的(unmasked) 非屏蔽中断(Nonmaskable interrupt) 只有几个特定的危急事件才引起非屏蔽中断。如硬件 故障或是掉电

13 中断 非屏蔽中断与可屏蔽中断

14 中断 CPU可以将屏蔽所有的可屏蔽终端 Eflags中的IF标志: 0=关中断; 1=开中断。
内核中使用cli和sti指令分别清除和设置该标志

15 异常 异常分为: 处理器探测异常 编程异常 由CPU执行指令时探测到一个反常条件时产生,如溢出、 除0错等
由编程者发出的特定请求产生,通常由int类指令触发 通常叫做“软中断” 例如系统调用

16 异常 对于处理器探测异常,根据异常时保存在 内核堆栈中的eip的值可以进一步分为: 故障(fault):eip=引起故障的指令的地址
通常可以纠正,处理完异常时,该指令被重新执行 例如缺页异常 陷阱(trap):eip=随后要执行的指令的地址。 异常中止(abort):eip=??? 发生严重的错误。eip值无效,只有强制终止受影响 的进程

17 中断向量 每个中断和异常由0~255之间的一个数(8位)来 标识,Intel称其为中断向量。 非屏蔽中断的向量和异常的向量是固定的
可屏蔽中断的向量可以通过对中断控制器的编程来改变 在保护模式下, 中断向量表由 IDT(中断描述符表)代替 IDT 也是描述符表, 其中的一个描述符即门描述符 IDT 将一个中断向量与一个描述符对应

18 中断向量 保护模式下的中断和异常

19

20 中断描述符表 中断描述符表是一个系统表,它与每一个中断或 者异常向量相联系 CPU的idtr寄存器指向IDT表的物理基地址
每个向量在表中有相应的中断或者异常处理程序的入口 地址。 每个描述符8个字节,共256项,占用空间2KB 内核在允许中断发生前,必须适当的初始化IDT CPU的idtr寄存器指向IDT表的物理基地址 lidt指令

21 门描述符 中断门和陷阱门 任务门不考虑 进入陷阱门时, 系统不会进入关中断

22 中断和异常的处理 异常或中断的设计是为了实现从用户态到核态的 转换,同时实现对特权级代码的保护
i386采用两个机制来实现这一目标:IDT和TSS IDT(Interrupt Descriptor Table)制定了256个中断 入口,其中前32个用于异常(traps或exceptions), 后面的(中断号>31)用于异步中断(interrupts)的处 理。 用户程序在运行过程中产生异常或者中断后,需 要将产生中断的地方存储起来,以便在处理完中 断后返回,可是存在什么地方呢?这里就要用到 TSS(Task State Segment)

23 TSS(Task Statement Segment)
本来Intel设计TSS的初衷是想通过这个段,来实现操作 系统中多任务的切换 但使用这个切换任务,会占用很多CPU的时间,并且打 破CPU的流水。因而,Linux和Windows都没有采用 TSS用作切换任务 TSS记录着“I/O权限位图”。另外TSS中还记录着0-2 环的esp和ss寄存器。当外环(如ring3)进入内环(如ring0) 时,会自动加载TSS中内环的esp和ss。那为什么tss没 有记录ring3的esp和ss呢?这是因为,外环进入内环时, 会将这些压入堆栈。当从内环返回外环时,从堆栈中恢 复就可以了

24 TSS TSS 的结构 你只需要关注 ss 和 esp
当从ring 3到ring 0的过程中, 会将断点通过压栈存储到 ss0 和 esp0 指向的堆栈空 间

25 中断和异常的硬件处理 1. 确定与中断或者异常关联的向量i(0~255) 2. 读idtr寄存器指向的IDT表中的第i项
3. 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符 4. 确定中断是由授权的发生源发出的。 中断:中断处理程序的特权不能低于引起中断的程序的 特权(对应GDT表项中的DPL vs CS寄存器中的CPL) 编程异常:还需比较CPL与对应IDT表项中的DPL

26 中断和异常的硬件处理 5. 检查是否发生了特权级的变化,一般指是否由用户 态陷入了内核态。 如果是由用户态陷入了内核态,控制单元必须开始 使用与新的特权级相关的堆栈 a,读tr寄存器,访问运行进程的tss段 b,用与新特权级相关的栈段和栈指针装载ss和esp寄存器。 这些值可以在进程的tss段中找到 c,在新的栈中保存ss和esp以前的值,这些值指明了与旧特 权级相关的栈的逻辑地址

27 中断和异常的硬件处理 6. 若发生的是故障,用引起异常的指令地址修改cs和 eip寄存器的值,以使得这条指令在异常处理结束 后能被再次执行
7. 在栈中保存eflags、cs和eip的内容 8. 如果异常产生一个硬件出错码,则将它保存在栈中

28 堆栈变化 发生中断或异常后堆栈的变化

29 中断和异常的硬件处理 9. 装载cs和eip寄存器,其值分别是IDT表中 第i项门描述符的段选择符和偏移量字段。 这对寄存器值给出中断或者异常处理程序的 第一条指定的逻辑地址

30 中断和异常的跳转

31 系统调用

32 系统调用 我们在这里用中断一词代表了多个概念, 其 中包括了系统调用 系统调用号和中断号进行区分 因此系统调用你也可以像中断处理一样实现
中断号: IDT 表中的索引 系统调用号: 函数的标识符 因此系统调用你也可以像中断处理一样实现

33 系统调用 你可以将所有系统调用使用 int 0x80 号中断 进行处理, 当然你需要输入一些参数:
实际的值 用户态进程地址空间的变量的地址 甚至是包含指向用户态函数的指针的数据结构的 地址 每个系统调用至少应该有一个参数, 即系统 调用号, 以确定将要调用哪个函数处理 Lab2 不要求一定以何种方式完成库函数的 实现

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

35 系统调用 我们在 do_irq.S 中将各个寄存器的值压栈 并调用中断处理函数 irq_handle(struct TrapFrame * tf) TrapFame 结构中保存了7个寄存器的值, 通 过写入寄存器的系统调用参数即可实现你需 要的参数传递

36 加载用户程序

37 加载用户程序 我们先来看一下我们现在的磁盘 Kernel App Sector 1 2 …… 201 Bootloader

38 加载用户程序 0x???????? Physical Memory App Stack App 0x00200000
Kernel Stack Kernel 0x Bootloader 0x00007C00 0x

39 加载用户程序 用户程序文件格式为 ELF 加载方式可以复制内核的加载方式
加载后不要着急跳转运行, 我们要对用户空间做一定 的配置, 因为内核运行在 ring0 而用户程序则运行在 ring3

40 配置 GDT 表项 我们在 GDT 表中初始化了用户代码段和用 户数据段, 但是没有填充相关字段, 你需要 在加载完用户程序后将代码段基地址以及数 据段基地址根据用户程序的地址重新初始化 用户段在这里都将 DPL 置为 3, 即用户程序 应该工作在 ring3

41 用 IRET 进入 ring3 在 IA-32中断机制中我们介绍了 IRET 指令 具体做了哪些工作, 但是你发现这些工作都 是硬件会帮你执行的 你需要为 IRET 指令在栈中压入相关内容: 用户堆栈段寄存器 SS 用户栈顶指针 ESP 标志寄存器 EFALGS 用户代码段寄存器 CS 用户指令寄存器 EIP

42 内存权限 作为工作在用户态的用户程序, 并不具有权 限在视频映射的显存地址中写入任何内容 不能向其他程序的内存中修改数据
将数据段限制在自己的数据段内即可

43 库函数

44 库函数 Lab2 要求完成 lib 目录下的格式化输出 printf 函数 测试用例可以在课程网站上获取 要求输出到屏幕
同时也可以输出到串口

45 Lab2 终…


Download ppt "Lab2 系统调用 2016-3-21."

Similar presentations


Ads by Google