这篇文章主要介绍操作系统的启动,中断、异常、系统调用的特征和差别,以及处理流程(机制)。
BIOS 是一种固化在计算机主板上的软件程序,其中的一个主要作用就是:启动计算机 —— 当你启动计算机时,BIOS 是第一个被执行的程序。它负责进行硬件自检(POST,Power-On Self-Test)以及初始化计算机的硬件设备,包括处理器、内存、硬盘、显卡等。BIOS 还负责加载操作系统的引导程序(BootLoader)。
操作系统启动过程可以概括为以下几个步骤:
计算机启动时,BIOS 从一个特定地址(CS:IP = 0xF000:FFF0)开始执行,这两个寄存器合在一起可以形成一个具体的物理内存地址。BIOS 就从这个内存地址开始执行 POST(加电自检)、寻找显卡和执行 BIOS。
段寄存器(CS)和指令寄存器(IP)是计算机中的两种不同类型的寄存器:
段寄存器 是用于存储内存中的段地址的寄存器。在计算机中,内存被划分为多个段,每个段都有一个唯一的段地址。段寄存器存储着当前程序正在访问的段的地址。当程序需要访问内存中的数据时,它会使用段寄存器中的地址来确定要访问的段,并将其与偏移地址(存储在其他寄存器中)相加以获取最终的物理地址。
** 指令寄存器(也称为程序计数器)** 是用于存储下一条要执行的指令的地址的寄存器。在计算机执行程序时,指令寄存器中保存着当前正在执行的指令的地址。当一条指令执行完毕后,指令寄存器会自动增加,以指向下一条将要执行的指令的地址。这样,计算机可以按顺序执行存储器中的指令序列。指令寄存器的值的改变决定了计算机下一步要执行的操作。
BIOS 负责加载 BootLoader:BIOS 会从预设的启动设备(如硬盘、光盘、USB 等)中加载引导程序(BootLoader)到内存中。引导程序通常位于硬盘的特定扇区或光盘的启动区。
引导程序的工作:引导程序负责初始化硬件(如 CPU、内存等),加载操作系统内核,并将控制权交给内核。它还可以提供多个操作系统的选择菜单(如 GRUB),以供用户选择启动的操作系统。
BootLoader 放在硬盘的第一个主引导扇区(512 字节)。这样,BIOS 从硬盘的第一个扇区寻找,一下便能找到 BootLoader。
BIOS 负责加载 BootLoader:将 BootLoader 从磁盘的引导扇区加载到 0x7C00 内存地址处。
BootLoader 负责加载 OS:将操作系统的代码和数据从硬盘加载到内存中。之后,控制权交给到 OS(跳转到 OS 的起始地址)。
操作系统与设备和程序之间的交互可以通过中断、异常和系统调用来实现。
中断(hardware interrupt):是指外部事件(如硬件设备请求、定时器中断等)打断程序的正常执行,引发操作系统的处理程序来处理相应的事件。通过中断,设备可以向操作系统发出请求,操作系统可以响应并进行相应的处理。
异常(exception):是指程序执行过程中出现的错误或异常情况,如除零错误、访问非法内存等。当发生异常时,操作系统会捕获并进行相应的处理,例如终止异常程序、显示错误消息等。
系统调用(system call):是应用程序通过操作系统提供的接口来请求操作系统的服务。通过系统调用,应用程序可以访问操作系统提供的功能,如文件读写、网络通信、内存管理等。应用程序通过系统调用将请求传递给操作系统,操作系统执行相应的操作,并将结果返回给应用程序。
中断来源于外设:来自不同的硬件设备的计时器和网络的中断。
异常来源于不良的应用程序:非法指令或者其他坏的处理状态(如:内存出错)。
系统调用来源于应用程序:应用程序主动向操作系统发出服务请求。
异步:应用程序不知道什么时候会发生
同步:执行到某一条指令一定会发生该事件
交互方式 | 来源 | 处理时间 | 响应状态 |
---|---|---|---|
中断 | 外设 | 异步 | 持续,对用户应用程序透明 |
异常 | 不良的应用程序 | 同步 | 杀死或重新执行指令 |
系统调用 | 应用程序 | 同步或异步 | 等待和持续 |
中断是外设的事件,异常是内部 CPU 的事件。中断和异常迫使 CPU 访问一些与中断和异常相关的功能和服务。
操作系统的中断处理流程包括硬件中断处理和软件中断处理两个部分。
硬件中断 处理流程如下:
软件中断 处理流程如下:
总的来说,中断处理流程包括 中断信号的检测、上下文的保存与恢复、中断处理程序的执行 等步骤,以保证操作系统能够及时响应硬件设备的请求或软件的触发。
应用程序完全不会感知到中断的产生。
操作系统的异常处理流程如下:
总的来说,异常处理流程包括 异常信号的检测、上下文的保存与恢复、异常处理程序的执行 等步骤,异常处理流程的目的是在程序出现异常时能够及时处理异常情况,保证系统的稳定性和可靠性。
系统调用来源于应用程序,需要操作系统提供服务,这些服务需要操作系统来执行,这个过程就需要一个接口:系统调用接口。应用程序访问主要是通过高层次的 API 接口,而不是直接进行系统调用。
三种最常用的 APIs:
特点:
用户态:操作系统运行中,CPU 所处的特权级别特别低,不能访问特权指令、I/O 指令。
内核态:操作系统运行中,CPU 所处的级别很高,可以执行任何一条指令,包括特权指令、I/O 指令。
系统调用 :触发 CPU 从用户态到内核态的转换。切换程序和内核的堆栈,需要一定的开销,但是换来了安全。
系统调用是跨越操作系统边界的开销(值得的且必须的,保证了操作系统的安全性):
「内核态独立地址空间」是指在操作系统中,内核和用户程序所使用的内存地址空间是相互独立的。
「更新页面映射权限」是指在操作系统中,对虚拟内存中的页面进行权限的调整或修改。
在虚拟内存管理中,操作系统将物理内存空间映射到进程的虚拟地址空间中,形成了一种虚拟内存映射。每个页面都有对应的权限,例如读、写、执行等。当需要修改某个页面的权限时,就需要进行页面映射权限的更新。
更新页面映射权限的具体操作包括:
通过更新页面映射权限,操作系统可以 实现对进程的内存访问控制,保证系统的安全性和稳定性。
应用程序不能直接访问外设,而要通过操作系统的原因主要有以下几点:
参考资料:
1:https://github.com/OXygenMoon/OperatingSystemInDepth
2:https://blog.csdn.net/weixin_53407527/category_11825873.html