加载运行操作系统,建立并发运行环境的过程

一.加载运行操作系统

1.开机键按下之前:

  基本只有 RTC 和 CMOS 在 RTC 电源供电的情况下才能正常工作

RTC 用以保持机器内部时钟的运转,这也是为什么我们的计算机关机之后再次启动时间还是准确的(不考虑操作系统启动后,利用网络同步时间)。而 CMOS 是电脑主板上的一块可读写的RAM芯片。因为可读写的特性,所以在电脑主板上用来保存 BIOS 设置电脑硬件参数后的数据。在计算机领域,CMOS 常指保存计算机基本启动信息(如日期、时间、启动设置等)的芯片。

  在关机状态下,只有 RTC 、EC 以及南桥部分组件在工作。RTC 维持着计算机的时钟和 CMOS 信息,而 EC 则在等待用户按下开机键。当然 EC 还负责电池的充放电的检测,指示灯,功能键等功能。

2.开机按钮按下后(硬件环境):

计算机启动的过程先通过简单的程序读入内存,执行后再载入更多程序和代码来执行,直到操作系统被载入执行为止。
要让计算机能够启动CPU,内存,计算机都要IO工作

(1)前奏

CPU老大还没动,小弟先动
  ATX电源系统对 IO芯片,、EC(嵌入式控制器,单片机),+5V标准电压(+5V Stand-By )为开机电路和需要唤醒机器的WOL(Wake-up On Lan)和 USB 等设备提供电源”,不会为 CPU 等提供工作电压。

  EC 收到开机信号,给南桥(南桥负责与低速设备(硬盘/USB)通信,时钟/BIOS/系统管理/旧式设备控制,并且与北桥通信)发送信号,南桥回应ES(单片机)LP_S5#(退出 S5 关机状态),SLP_S4#(退出 S4 休眠状态),SLP_S3#(退出 S3 待机状态)

  南桥发送发送PLT_RST#给北桥(负责与CPU通信,并且连接高速设备(内存/显卡)),紧接着向 CPU 发送 PWRGOOD#信号。北桥接收到南桥的信号,默念一秒钟后,向 CPU 老大发送了CPU_RST#信号。

笔记本采用 EC,台式机很多用SIO(Super I/O)或者定制芯片,嵌入式设备以及手机采用PMIC(Power Management IC)。以上的故事都是基于台式机形式,但是我们选用 EC 来解释电源时序控制过程,是考虑到国内关于 EC 的资料较多。与台式机不同的一点是,笔记本因为有锂电池的原因,在没有接入电源适配器前,EC 以及IO设备就已经处于工作状态了。这也是为什么我们打开笔记本电脑,按下开机键,系统能接收到这个信号,并准备开始工作。

(2)后半奏:

CPU老大启动了,CPU坐上了王座
CPU 醒来,整个系统中没有指令存在,那也只是一堆硬件被供电了。

~这当然是不可能的事情。最早的时候,工程师们用它来比喻,计算机启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序!早期真的是这样,必须想尽各种办法,把一小段程序装进内存,然后计算机才能正常运行

  CPU 一醒来,毫不迟疑,立马开始工作。CPU 知道自己的使命,第一步就是取地址0xFFFFFFF0(只读)内存上的指令
CPU 设计时固化的功能。CPU拿到指令后执行,发现这条指令是告知自己,下一次去另一个地址取指(跳转指令0xF000,0xE05B])。

3.软件环节

(1)BIOS

  BIOS 启动,先进行自检,检查内存、显卡、磁盘等关键设备是否存在功能异常,会有蜂鸣器汇报错误,无错误自检飞快结束,BIOS 调用显卡 BIOS 代码,通常在 C0000H 处(此时显示器已经可以显示显卡 BIOS 程序信息,或许是个 logo?)BIOS 调用其他关键设备的 BIOS 代码来初始化他们。

IOS 芯片中也保存了不少指令,形成的功能包括:
  自诊断程序:读取 CMOS 中的内容获得硬件配置信息,并对其进行自检和初始化;完整的 POST(Power On Self Test) 自检将包括CPU、640K基本内存、1M以上的扩展内存、ROM、主板、 CMOS RAM、串并口、显示卡、软硬盘子系统及键盘测试。
  CMOS 设置程序:引导过程中,用特殊热键启动,进行设置后,存入CMOS RAM中;对应 Dell 计算机启动时我们按F12,进入的 BIOS 设置界面。
  系统自举装载程序:在自检成功后将磁盘相对 0 道 0 扇区上的引导程序装入内存,让其运行引导操作系统;
  主要 I/O 设备的驱动程序和中断服务:系统硬件的变化由 BIOS 隐藏,程序使用 BIOS 功能而不是直接控制硬件。不过现代操作系统会忽略 BIOS 提供的抽象层并直接控制硬件组件。

(2)操作系统引导:Bootloader

  Bootloader 最直观的功能就是将操作系统加载到内存中。首先可以考虑在硬盘上存在多个操作系统的情况下,操作系统的加载方式过程可能就不同。如果让 BIOS 来考虑各个操作系统待加载到内存中的目的地址,这会导致 BIOS 程序的膨胀。而 BIOS 程序是固化在 BIOS 芯片中,正常情况下是无法修改的,解决加载新的操作系统出现问题就会很麻烦。而保证 BIOS 的正常功能就要降低 BOIS 的复杂性,那么适配不同操作系统的任务谁来做呢?那当然就是 bootloader 啦。并且在嵌入式环境下,操作系统的加载并不仅仅从磁盘上加载,还可能是Nor Flash 、NAND flash、USB 甚至是网络。那么 Bootloader 就应该实现基本的网络功能,例如著名的开源项目 U-Boot就是这样做的。当然本文在这里只是抛砖引玉,为什么要分出一个 Bootloader 层,可以从很多方面分析这样做的优势。

普通的 Bootloader 都需要实现什么功能呢:

1.初始化硬件设备
2.为操作系统准备RAM空间
3.将操作系统代码载入到RAM中
4.设置堆栈执行环境,为高级语言(如 C 语言)提供执行环境。这里要多说一句,操作系统并不都是 C 语言写的哦。现在 Rust 语言接近 C 语言性能,并且因为其提供的安全性,已经被用来写操作系统了。
5.将控制权交给操作系统。到这一步,系统的完整启动也就结束啦。之后就是操作系统主宰的世界了!

二.建立并发运行环境

1. 系统启动与内核初始化

(1)引导加载(Booting):

当计算机启动时,BIOS/UEFI 读取引导程序(如 GRUB、LILO)并加载操作系统内核到内存。
内核开始初始化硬件:CPU、内存、外设等,并设置特权级(通常内核运行在特权级 0)。

(2).多核系统初始化(SMP):

在多核环境下,内核需要启动所有 CPU 核心,并通过中断控制器(如 APIC)协调多核调度。

各 CPU 核心会加载各自的栈空间,准备独立的执行环境。

2. 进程与线程管理机制搭建

(1)创建内核线程与初始进程:

   第一个线程(如 idle 线程)由内核创建,用于在系统空闲时执行。

  创建第一个用户级进程(如 init),后续所有进程都从它派生。

(2)初始化 PCB/TCB(进程/线程控制块):

  操作系统会为每个进程和线程分配 PCB 和 TCB,记录:

  进程 ID(PID)、父进程 ID(PPID)

  进程状态(就绪、运行、阻塞等)

  优先级、时间片、CPU 核心绑定信息

  程序计数器(PC)、寄存器值、栈指针(SP)

(3)调度队列建立:

  设置多个调度队列:

  就绪队列:等待被调度的进程。

  等待队列:因 I/O 或资源不足而阻塞的进程。

  僵尸队列:等待被父进程回收的僵尸进程。

3. 内存管理机制搭建

(1)虚拟内存初始化:

  为每个进程创建独立的虚拟内存空间,映射到物理内存或磁盘上的交换空间。
  设置页表(Page Table),实现虚拟地址到物理地址的转换。

(2)栈与堆空间分配:

  为每个线程分配独立的栈空间(存放函数调用、局部变量)。
  堆空间由动态分配器(如 malloc、new)在运行时管理。

(3)内存保护机制:

  配置内存访问权限,防止一个进程访问另一个进程的内存。
  设置段错误(Segmentation Fault)机制,避免非法访问。

4. 并发控制机制创建

(1)同步原语初始化:

  配置互斥锁(Mutex)、读写锁(RWLock)、自旋锁(Spinlock)等,用于线程间共享资源的互斥访问。
  创建条件变量(Condition Variable),支持线程的同步与事件等待。

(2)中断与异常管理:

  设置时钟中断,用于周期性触发调度器,实现任务切换。
   配置外设中断(如键盘、网络),确保设备事件能被及时处理。

5. 调度机制搭建

(1)调度器初始化:

  选择调度策略,如:
  时间片轮转(RR): 每个进程轮流获得 CPU。
  优先级调度: 优先级高的进程先执行。
  多级反馈队列: 动态调整进程优先级,兼顾响应速度和吞吐量。

(2).上下文切换机制:

  保存当前进程的 CPU 寄存器状态(如 PC、SP、寄存器等)到 PCB。
  恢复下一个进程的寄存器状态,实现无缝切换。

6. 通信机制搭建

(1)进程间通信(IPC):

配置消息队列、共享内存、信号、套接字等机制,确保进程间数据交换安全高效。

(2)设备与文件系统管理:

为进程提供统一的接口来访问文件系统和外设(如磁盘、网络)。

7. 启动并发运行环境

(1).创建系统守护进程:

  启动各种系统服务(如网络管理、日志服务、作业控制等),确保系统功能正常运作。

(2).进入调度循环:

   a.系统进入无限循环状态:
  b.检查就绪队列,选择下一个进程。
  c.切换上下文,交出 CPU 控制权。
   d.处理 I/O 中断、定时器事件等外部输入。
  e.不断重复,直到系统关机或重启。

参考文献:
计算机是如何启动的?从未上电到操作系统启动

posted @ 2025-03-26 21:13  pptlv  阅读(97)  评论(0)    收藏  举报