操作系统简介
我们为什么需要操作系统?
最早的计算机是没有操作系统的,程序以独占的方式运行于硬件之上。
然而,当我们希望在一个硬件上运行多个程序时,资源的分配成了一个大问题。如对于内存资源,程序之间无法协商使用的内存,如果两个程序同时使用同一块内存,那么两个程序都很可能会发生错误。
因此,一个可以统一管理各种资源的程序是相当重要的。这个程序就是我们现在所说的操作系统。
操作系统功能
需要注意的是,操作系统本质上就是一个程序,在本质上和其他程序没有区别。操作系统不是魔法,所有的功能都是利用了硬件特性结合软件工程实现的。
下面我们会对一些核心的功能进行简单介绍。
用户态/内核态
你可能会问,虽然说操作系统本质上就是一个程序,那么其他程序怎么不能成为操作系统呢?如果其他程序能成为操作系统,那么操作系统的资源管理不就无法完成了吗?
实际上,一个程序是否能成为操作系统,取决于其所在的特权状态。如果没有特权,那么这个程序就是普通的用户态程序。
特权状态及其转移是通过硬件(或者模拟硬件的软件)实现的。也就是说,硬件维护了一个特权状态,并且提供了一些切换特权的方式。
从高特权级到低特权级是可以很轻易完成的,因为这个操作中权限是严格变小的。反过来,从低特权级到高特权级的操作也是经常发生的。这可能有一些反直觉,为什么可以从低特权级别转到高特权级别呢?要回答这个问题,我们需要思考为什么需要从低特权切换到高特权。注意到当我们主动地需要操作系统做一些事情1时,那么我们就是需要从低特权的用户程序进入到高特权的内核。为了防止出现低特权级别程序获得高特权后做一些破坏性的事情,我们会限制切换特权级后 PC 的值。
这被称为 system call,即系统调用。
在 RISCV 中,一共有 4 个特权等级,从高到低分别是 machine mode、hypervisor mode(给虚拟机预留,我们内核用不到)、supervisor mode 和 user mode。
Machine mode 负责处理一些非常底层的工作,比如 timer interrupt。
Supervisor mode 即为内核所在的特权级,会完成内核绝大多数的工作。
User mode 为用户程序所在的特权级。
RISCV 根据不同的需求,设计了一套同步和一套异步的切换机制,具体参见陷入 (Trap)、中断 (Interrupt) 与异常 (Exception) 介绍。
内存管理
内存管理是内核中很重要的一个功能。
管理用户态程序的方法是使用虚拟内存。虚拟内存地址空间由页表控制,可以控制每个页面的访问权限(读/写/执行),以及其他控制权限。页表由内核控制。
除了管理用户态程序的地址空间,内核还需要处理内存的分配。内存分配对象是内核以及所有用户态程序。内核需要负责分配和回收内存。
进程管理
进程是资源管理的基本单位。内核中需要管理好每个程序使用的资源。
外部设备管理
除了上面的哪些功能,内核还需要管理硬件,并为用户态程序做好设备的抽象,方便设备的使用。
操作系统流程
一个操作系统从入口点开始大致需要做下面的几个事情:
- 设置正确的环境(包括中断等);
- 进入内核所在的特权级;
- 进行内核组建的初始化;
- 运行第一个应用程序;
- 为所有的应用程序服务,并对应用程序进行合理的调度。