遨游在内存中的硬件启动过程

遨游在内存中的硬件启动过程

2024.9.28 .NET Conf 介绍话题,话题来自我之前对硬件启动过程的好奇

叠甲

NOTE: 我并非一个专于底层设计的开发者,对计算机的底层结构仍然有很多的不解与困惑,因而本文可能包含不少问题,如果发现了错误,请一定要在联系我/评论区发送你的修改意见

一时兴起

相比大家学习计算机时可能会产生这样的困惑:计算机是怎么被拉起启动的,也许学习”计算机组成原理”能回答你的一部分问题,它会告诉你计算机上电后会进行一系列的检查,接着调用 BIOS,进入 Bootloader 阶段,最终拉起 OS ,进入熟悉的页面

但是在这之中仍然有很多未知的事情,例如,计算机进行的这一系列检查的过程理论上讲也是一种过程,这种检查的逻辑在没有软件的阶段是谁来解决的?在内存被初始化前,其无法存储信息,此时此刻 BIOS 是怎么被执行的?

接下来的文章内容会对解决这些对你们毫无用处的问题提供一些可能解释不清楚的帮助

基础知识

照顾到大家有些同学可能对 计算机组成原理/体系结构 并没有太多的了解,我们来简单讲一讲计算机的基础概念

CPU在加电后,它首先会调用 BIOS/UEFI 会进行一系列操作,比如 上电检查,切换保护模式等等。这些操作目的是检查硬件,训练内存,为下一阶段提供环境,最后会调用你磁盘上的下一段程序,一般是 Bootloader 常见的有 Windows 下的 Windows Boot Manager ,Linux 下的 SystemBoot/Grub 等等,而 Bootloader 会拉起 OS ,OS 在启动阶段将接过 BIOS/UEFI 与 Bootloader 为你准备的所有前置环境,由操作系统掌管权力开启新的天地

通常我们简单讲讲就会这么解释。对于开发者来说,再底层也不过就是 Bootloader 级别的,在裸机上写 OS 等等的操作。但其实这个裸机一点都不”裸”,它具有相当完善的环境,以至于你可以进一步开天辟地,从而有了 OS。

我们今天就讨论一些比 Bootloader/OS 还要底层的 BIOS

RAM & ROM 在 CPU 看来都是 Memory

如果说大家写代码写多了,会时常觉得 Memory 貌似是一种可读可写的东西,但是我们要指出 Memory 并不是那么简单的东西,事实上 ROM 也是一种 Memory

我们常说 BIOS/UEFI 是 ROM ,所以它也是内存,内存要怎么访问?当然是通过地址,CPU 才不管你是内存条还是一个 BIOS 芯片,CPU 只是需要像读取普通的 DRAM 一样读取数据就行了,而作为从属于 CPU 完全听从其指导的芯片就考虑的多了

也许大家很难理解,但是事实上是,存储器前都不是直连 CPU 的地址总线的,而是通过了一个 内存控制器(Memory Controller,简称 MC)的东西,它的真身本体是在北桥当中的。而在现在的 CPU 中,北桥已经被完全封装在 CPU 内部的,内存控制器会将 地址总线 分别映射到输出总线,连接到实际的设备上(比较常见的是通过PCIe总线)

但上古时期的 8086 确实是通过地址总线直连内存颗粒的

揭秘启动过程

在计算机启动到 Reset Vector 所指向的第一条指令被 CPU 运行之间的各种硬件安全检查这些纯硬件的专业部分我们先按下不表,我们来看计算机怎么获取到 BIOS 里的信息的

第一条指令

首先,CPU 核会发出一个取指的指令,这个指令会传递给北桥,北桥此时此刻也是一个被 reset ,北桥内有一个被成为 PAM 的寄存器,每个 PAM 寄存器分为两个半字节,半字节有两个保留位,一个读使能和写使能位。每个半字节对应 16k 的 内存空间,但 PAM[0] 对应的是 32k。

通过设置 PAM 寄存器的值可以规定某一块 CPU 核的内存空间所对应的是实际真正的 RAM ,还是转发到 PCI 域中,Reset Vector 所在的地址空间对应的 PAM 寄存器缺省的值就是将 CPU 取指的指令转发到 PCI 域中,那么取指的信号就从 DMI 总线(这其实是基于 PCIe 总线的),发送到南桥,南桥芯片组又会把这个取指信号处理发给下一级,最终到达 BIOS ROM 芯片上,原路返回,这样 CPU 就能获取到第一条命令了,接下来的事情就都简单起来了

顺带一提,在 BIOS ROM 是一种支持在线运行的存储器,这意味着指令直接读取就运行,但是对 BIOS ROM 的一切写指令都将被中间过程给拒绝掉

在 BIOS ROM 运行的同时,机器会将 BIOS ROM 的内容复制到 RAM 中,在内存控制器给与这一块 RAM 只读的属性,更改 PAM 的值,让它从转发到 PCI 域的状态切换成直接访问 RAM,提高 ROM 运行的效率

简单认识一下 UEFI

UEFI 的七个阶段

  1. SEC(安全验证)
  2. PEI(EFI前期初始化)
  3. DXE(驱动执行环境)
  4. BDS(启动设备选择)
  5. TSL(操作系统加载前期)
  6. RT(Run Time)
  7. AL(系统灾难恢复期)

我们不会对此进行详细的介绍,UEFI 提供了一种统一的方式,它所干的事情就是做安全检查,为操作系统启动准备环境

UEFI 时期已经完成了对文件系统的支持,他会读取即 EFI 系统分区中的 *.efi 文件,并且启动它,通常来说这个程序是一个 Bootloader ,但是其实也能是其他任何东西,总之这就是我们常说的裸机程序了

好用的工具推荐

RW-Everything https://rweverything.com/
奇妙的小工具,能让你的内存旋转