说明:该系类文章更多的是从从哲学视角看 操作系统 这门学科。同时也是 操作系统的学习笔记总结。因为博主 这些年主要是以研究安卓系统和 嵌入式Linux为主,因此这个系类文章也是这两个领域不可或缺的基石之一,尤其是对操作系统感兴趣的伙伴可特别关注。
3 操作系统的基本概念
在软件的很多设计中因为要考虑各种因素而折中,导致结果差不多就可以了,而这一思想也体现在操作系统中。
3.1 计算机硬件基本知识
从概念上讲,计算机的结构是总线型结构,所有设备通信均要通过总线。如图所示:
为了提高计算机的效率,工厂的流水线结构被采用了。将计算机的功能分为多个梯级,每条指令分拆为同样多的步骤,使指令在流水线上流动,直到最后一个梯级时指令执行完毕。如图:
为了进一步提高计算机的效率,在流水线的基础上出现了多条流水线、超标量计算和指令字等多指令发射机制;同时这些机制也增加了计算机的复杂性,并对操作系统和编译器提出了更高的要求。超标量发射的体系结构如图:
这种结构实现了多路复用(multiplex)和反多路复用(de-multiplex),从而提高每个功能单元的利用率和整个系统的吞吐量。除指令执行单元,还有存储架构。典型的存储架构如下所示:
这个存储结构不是最好、最快的,但是从商业的视角来看是性价比最高的。
中断是一个计算机里面最重要的机制之一,它的基本原理:设别完成自己的任务后向CPU发出中断,CPU判断优先级,然后确定是否响应。如果响应,则执行中断程序并在中断后执行原来的程序。一个磁盘中断的响应流程如下:
总结如下:
- CPU向磁盘控制器发出读写请求
- 磁盘控制器在操作系统结束后发出中断
- 中断控制器将中断传送给CPU
- CPU响应中断
3.2 抽象
- 抽象源于具体,又超越具体;源于现实,有超越现实。从发现中得出规律,利用规律创造新的东西。
- 具体的计算机硬件,CPU、内存、I/O设备等源于显示,却给人以强于现实的东西。
3.3 内核态与用户态
- 内核态:也称为特权态,可访问的资源多,不受限制。可靠性,安全性要求较高。涉及计算机根本运行的事情都在该状态下运行,对实时性要求特别高的也在该状态下运行。
- 用户态:也称为非特权态,可访问的资源受到限制。可靠性,安全性要求较低。只与用户数据和应用相关的程序在该状态下运行。
windows操作系统的内核态与用户态的界限如图所示:
3.3.1 态势的识别
在识别用户当前所处的态势是用户态还是内核态需要做的只是判断一个位的标志,即只是一个状态字。一个程序运行的时候,CPU是什么状态,程序就是什么状态。
3.3.2 内核态与用户态的实现
要限制一个程序对资源的访问,需要对每一条指令进行检查才能完成,这种检查就是地址翻译。程序的每条命令都必须通过地址翻译,通过对翻译的控制,可以限制程序对资源的访问。系统处于内核态时,内核程序可以绕过内存地址翻译而直接执行特权指令。
3.4 操作系统结构
起初,操作系统因为规模小而没有结构,而随着规模的不断扩大,结构在设计中变得越来越重要,层级思想,模块思想变得越来越有效;系统安全性、健壮性也开始体现重要性;操作系统开始变得异常复杂。整个层次的分配是模拟人类社会来做的。
3.5 进程、内存和文件
在任何时候,进程所占有的全部资源,包括分配给进程的内存、内核数据结构和软件资源形成一个进程核(core)。核快照(core image)代表的是进程在某一时刻的状态。 如果在linux/unix下编写程序,当出现段错误(segmentation fault)时,操作系统会自动进行核导出(core dump) ,把所有计算机的状态保存在一个文件中,这对调试的帮助很大。
内存与文件:
- 内存是进程存放的场所,内存的目的就是使得数据的读写具有高效率、高安全、高空间利用率和位置透明的特性。
- 文件是一种抽象,目的是使得用户的数据存放变得容易、方便、可靠和安全,这些要由文件系统来解决。
3.6 系统调用
系统调用:操作系统提供给应用程序的API。
系统调用按照功能分为6大类:
- 进程控制类
- 文件管理类
- 设备管理类
- 内存管理类
- 信息维护类
- 通信类
系统调用的过程分为3个阶段:
- 参数准备阶段
- 系统调用识别阶段
- 系统调用执行阶段
系统调用中参数传递方式:压栈或存放在寄存器里(一般是存放在寄存器里,多于有效寄存器的参数放在栈里)。比如:read系统调用的过程如下:
3.7 壳(shell)
本意是为了让不编程的用户来操作计算机而制作的一个终端,用来与用户进行交互,这个壳是一个覆盖在操作系统服务上的一个用户界面,既可以是图形界面,也可以是文本界面。
在linux/unix下,这个壳是shell终端,在windows下,这个壳是微软自己创建的power shell。
一个壳的功能有以下几项:
- 显示提示符
- 接受用户命令并执行
- 实现间接输入输出
- 启动后台程序
- 进行工作控制
- 提供伪终端服务
这个壳一旦启动,就会循环往复直到无穷,他所做的事情有:
#伪代码
loop: 显示命令提示符
等待用户输入命令
使用fork创建一个进程
使用exec在创建的子进程里执行输入的命令
goto loop