熟悉完操作系统的第一篇章,开始学习第二篇章,关于操作系统的介绍。

0猜你喜欢

操作系统系列文章

操作系统学习笔记 1概述

操作系统学习笔记 2操作系统介绍

操作系统学习笔记 3内存管理

操作系统学习笔记 4非连续内存分配

操作系统学习笔记 5虚拟内存

操作系统学习笔记 6页面置换算法

操作系统学习笔记 7进程管理

操作系统学习笔记 8CPU调度

操作系统学习笔记 9同步&互斥

操作系统学习笔记 10信号量&管程

操作系统学习笔记 11死锁

操作系统学习笔记 12进程间通信

操作系统学习笔记 13文件系统

2操作系统介绍

启动

  • 计算机体系结构概述
  • 计算机内存和硬盘布局
  • 开机顺序

中断、异常和系统调用

  • 背景
  • 中断、异常和系统调用相比较
  • 中断和异常处理机制
  • 系统调用的概念
  • 系统调用的实现
  • 程序调用与系统调用的不同之处
  • 开销

2.1操作系统的启动

2.1.1BIOS-》BootLoader-》OS

从计算机原理角度看,就三部分。CPU,内存和IO。

操作系统开始并没有放在内存里,直接让CPU去执行,实际上它放在DISK,硬盘里面。然后由BIOS(基本I/O处理系统)提供支持。这样就可以,一按电源,让计算机去监测各种外设,使得BIOS完成最基本的功能。检测完外设之后,才能加载相应的软件去执行。

OS是放在DISK上面的,除了OS之外,还有很简单的小程序叫BootLoader。BootLoader主要功能是加载OS的,让我们的OS从硬盘放到内存里面去,然后让我们的CPU可以执行操作系统。

下面是指令寄存器

两个寄存器合起来会形成一个具体的内存的地址,上电之后就会从这个地址运行BIOS。这个地址执行之后,会完成一系列工作,POST(加电自检),寻找显卡和执行BIOS。

开始显示画面,说明加载显卡显示驱动,另外还有键盘鼠标来控制这些操作以及数据存储存在地址上面,这些基本的操作都需要BIOS来进行初始化的检查。完成之后,BIOS将BootLoader从DISK放到内存里面。

BootLoader会放置在第一个硬盘的主引导扇区,BIOS就比较好找,那就能把它放到内存中去。第一个扇区是512个字节。BootLoader会将更复杂的OS从硬盘放到内存中去。

BootLoader找到硬盘的起始扇区,硬盘操作系统的起始扇区以及操作系统长度,然后把这块内容(可能包含几个硬盘的磁盘块)从硬盘中读到内存中。

2.1.2系统调用\异常\中断

操作系统与设备和程序交互

面向外设是中断和I/O处理的

面向应用程序是通过系统调用异常处理的

定义

  1. 系统调用(来源于应用程序)

    应用程序主动向操作系统发出服务请求

  2. 异常(来源于不良的应用程序)

    非法指令或者其他坏的处理状态(比如:内存出错)

  3. 中断(来源于外设)

    来自不同的硬件设备的计时器和网络中断

为什么应用程序不能直接去访问外设,而是需要通过操作系统操作系统是特别的软件,它对整个计算机有控制权。操作系统可以给上层应用提供一个简单一致的接口,使得上层应用不用去关注地下device的细节。针对不同device开发不同软件效率会很低,用于屏蔽底层的复杂性和差异性。

  • 在计算机运行中,内核是被信任的第三方
  • 只有内核可以执行特权命令
  • 为了方便应用程序

操作系统如何设计和实现中断、异常和系统调用。它们三者有什么区别和特点

操作系统区别特点 中断 异常 系统调用
源头 外设(键盘,鼠标,网卡,声卡,显卡) 应用程序意想不到的行为 应用程序请求操作系统提供服务(打开关闭文件,发送网络包)
处理事件 异步 同步 异步或同步
响应 持续,对用户应用程序是透明的 杀死或者重新执行意想不到的应用程序指令 等待和持续

异步:这个事件产生了,但是操作系统并不知道这个时间什么时候产生

同步:特定的指令触发某种请求让操作系统完成。

2.2 操作系统的中断、异常和系统调用

不同的外设产生一个中断都有一个编号,一个编号会对应一个地址,地址就会特定中断服务地址的。

操作系统收到了一个中断信号,会根据一个中断表,会查到对应中断服务进程的起始地址。

当产生中断之后,打断当前的正常执行来处理紧急的外设中断事件,然后中断事件结束之后会继续正常运行。

使得上面能正常,分两部分完成,硬件和软件两部分组成

硬件

  1. 设置中断标记[CPU初始化]
  2. 包括将内部、外部时间设置中断标记和中断事件的ID

软件

  1. 保存当前处理状态(线程)
  2. 中断服务程序处理
  3. 清除中断标记
  4. 恢复之前保存的处理状态

和中断类似,异常也是有对应的编号

  1. 保存现场
  2. 异常处理,包括杀死产生异常的程序和重新执行异常指令
  3. 恢复现场

系统调用有所区别

应用程序调用printf()会触发write系统调用,write会带有参数,比如哪个设备显示字符串和字符串的内容。操作系统获取到这两个参数之后,会去访问对应的设备,比如屏幕,让屏幕把字符串给显示出来。整个系统是操作系统去完成,而不是应用本身去完成。应用只需发一个请求交给操作系统即可,当操作系统完成这个请求之后,就会返回一个成功或者失败。这样应用就可以知道,应用程序做完这个请求之后可以继续完成其他的操作。

程序访问主要是通过高层次的API接口而不是直接进行系统调用。

  1. win32 API用于Windows

  2. POSIX API(通用API)用于POSIX-based systems,包括UNIX、Linux、Mac OS的所有版本

  3. Java API用于Java虚拟机JVM

  4. 通常情况下,于每个系统调动相关的序号

    系统调用接口根据这些序号为维护表的索引

  5. 系统调用接口调用内核态中预期的系统调用

    并返回系统调用的状态和其他任何返回值

  6. 用户不需要知道系统调用是如何实现的

    只需要获取API的了解操作系统将什么作为返回结果

    操作系统接口的细节大部分隐藏在API中,通过运行程序支持的库来管理

函数调用和系统调用的区别

函数调用的时候,是在一个栈空间的,完成参数的传递和参数的返回。系统调用的时候,应用程序和操作系统会使用各自的堆栈。当应用层程序发起系统调用之后,会切换到内核里面去执行,他需要去切换堆栈,同时还会有状态的切换,从用户态到内核态的切换。

这个堆栈和状态的切换,都需要额外的开销。即当系统调用的时候会比函数调用的开销大,操作系统会付出额外的时间代价,但换来的是安全的、可靠的。

额外开销的总结(跨越操作系统的开销)

  • 在执行时间上的开销超过程序调用
  • 建立中断/异常/系统调用号与对应服务例程映射关系的初始化开销
  • 建立内核堆栈
  • 验证参数
  • 内核态映射到用户态的地址空间(包括更新页面映射的权限)
  • 内核态独立地址空间(TLB后备缓冲区)