介绍
操作系统老师说, 平时面试学生或者毕业答辩的时候他都会问这个问题, 可见这个问题对于计算机专业的学生来说是如此重要. 那么, 从打开计算机电源到计算机的屏幕显示, 中间经历了哪些过程呢?
启动的英文是 boot, 来自于一个谚语
pull oneself up by one's bootstraps
通过拉自己的鞋带把自己拽起
这个很明显是矛盾的. 工程师早期用这句谚语用来比喻早期的计算机开机,
因为计算机启动需要运行程序, 而运行程序又需要计算机启动. 这个是一个很矛盾的过程. 直到后来开机程序被刷入 ROM 芯片后, 这个开机的 boot
大概过程是这样的:
- Turn on
- CPU jump to physical address of BIOS(In Intel it is 0xFFFF0)
- BIOS runs POST(Power-On Self Test)
- Find bootable devices
- Loads boot sector from MBR
- BIOS yields control to OS BootLoader
- 1. BIOS
BIOS 介绍:
BIOS(Basic Input/Output System)是基本输入输出系统的简称. BIOS 能为电脑提供最低级, 最直接的硬件控制与支持, 是联系最底层的硬件系统和软件系统的桥梁. 为了在关机后使 BIOS 不会丢失, 早期的 BIOS 存储在 ROM 中, 并且其大小不会超过 64KB; 而目前的 BIOS 大多有 1MB 到 2MB, 所以会被存储在 闪存 (Flash Memory) 中.
BIOS 设置程序是被固化到电脑主板上地 ROM 芯片中的一组程序, 其主要功能是为电脑提供最底层的, 最直接的硬件设置和控制. BIOS 通常与
硬件系统集成在一起(在计算机主板的 ROM 或 EEPROM 中), 所以也被称为 固件
如何运行
BIOS 存放在一个断电后不会丢失内容的 ROM 中, 这保证了 "拽着鞋带拉起自己" 的这种情况不会发生. 因为系统一上电或重置, 处理器要执行第一条指令的地址会被定位到 BIOS 存储器, 初始化开始运行. 在 X86 系统中, CPU 加电后跳转至 BIOS 的固定物理地址 0xFFFF0.
打开计算机电源, 计算机会首先加载 BIOS, 包含
CPU 相关信息
设备启动顺序信息
硬盘信息
内存信息
时钟信息
PHP 特性
...
硬件自检(Power-On Self Test,POST)
如果硬件出现问题, 主板会发出不同含义的蜂鸣 , 启动中止. 如果没有问题, 屏幕就会显示出 CPU , 内存, 硬盘等信息. BIOS 在执行完硬件自检和初始化后, 会将自己复制到从 0xA0000 开始的物理内存中并继续执行.
BIOS 代码包含诊断功能, 以保证某些重要硬件组件, 像是
键盘, 磁盘设备, 输出输入端口等等, 可以正常运作且正
确地初始化.
BIOS 产生的问题
开发效率低: 大部分 BIOS 代码使用汇编开发, 开发效率不言而喻. 汇编开发的另一个缺点是使得代码与设备的耦合程度太高, 代码受硬件变化的影响大.
性能差: BIOS 基本输入 / 输出服务需要通过中断来完成, 开销大, 并且 BIOS 没有提供异步工作模式, 大量的时间消耗在等待上.
功能扩展性差, 升级缓慢: BIOS 代码采用静态链接, 增加硬件功能时, 必须将 16 位代码放置在 0x0C0000~0x0DFFFF 区间, 初始化时将其设置为约定的中断处理程序. 而且 BIOS 没有提供动态加载设备驱动的方案.
安全性: BIOS 运行过程中对可执行代码没有安全方面的考虑.
不支持从硬盘2TB 以上的地址引导: 受限于 BIOS 硬盘的寻址方式, BIOS 硬盘采用 32 位地址, 因而引导扇区的最大逻辑块地址是 232(换算成字节地址, 即 232*512=2TB)
由于这些问题的存在, UEFI 横空出世
UEFI 中文名为统一可扩展固件界面 (英语: Unified Extensible Firmware Interface, 缩写 UEFI) 是一种个人电脑系统规格, 用来定义操作系统与系统硬件之间的软件界面, 作为 BIOS 的替代方案. 可扩展固件接口负责加电自检(POST), 联系操作系统以及提供连接作业系统与硬体的介面.
UEFI 与 BIOS 的几个区别
EFI 使用模块化, C 语言风格的参数堆栈传递方式以及动态链接形式构建的系统, 相对于 BIOS 而言跟容易实现, 容错和纠错特性更强, 减少系统研发的时间.
运行于 32 位或 64 位模式, 面对未来增强的处理器模式下, 能突破 BIOS 16 位代码的寻址能力, 达到处理器最大寻址.
UEFI 有良好的鼠标操控图形化界面, 在开机速度也比 BIOS 快不少
BIOS 过程
UEFI 过程
相对来说 UEFI 比 BIOS 少了一个硬件检测
即使如此, 本章启动过程还是着重于分析利用 BIOS 启动的过程.
2. 读取 MBR
MBR - 全称是 Master Boot Record(主引导记录或主开机记录), 是一个 512byte 的扇区, 位于磁盘的固定位置. 之所以叫 "主引导记录", 是因为其存在于驱动器开始部分的一个特殊扇区, 个扇区包含已安装的操作系统启动记载器和驱动器的逻辑分区信息. BIOS 完成 POST 和初始化之后, 会根据 CMOS 中设定的顺序选择引导的设备, 这个设备可以是 U 盘可以是硬盘. 若设置为硬盘, 则 BIOS 就会读取 MBR.MBR 里面包含了一段引导程序, 一个分区表和 Magic Number.
MBR 的结构
位置 | 作用 |
---|---|
1-445 字节 | 调用操作系统的机器码 (Call OS) |
447-510 字节 | 分区表 (Partition table) |
511-512 字节 | 主引导记录签名 (只有两个,0x55 和 0xAA,为 Magic Number),如果不是这两个幻数,就认为这是一个没有被分区的硬盘。 |
分区表的长度只有 64 个字节, 里面分为四项, 每项为 16 个字节. 所以一个硬盘只可以分四个一级分区, 又叫做 "主分区". 每个主分区的 16 个字节, 结构如下
位置 (字节) | 作用 |
---|---|
1 | 如果第一个为 0x80,表示该主分区是激活分区 (active),控制权将转交给此分区。几个分区中只能有一个是激活分区,其他都是非激活分区 (inactive)。 |
2-4 | 主分区的第一个扇区物理位置 (柱面、磁头、扇区号等) |
5 | 主分区的类型 分区类型符 |
6-8 | 主分区最后一个扇区的物理位置 |
9-12 | 主分区第一个扇区的逻辑位置 |
13-16 | 主分区的扇区总数,决定了主分区的长度 |
其中第 5 字节分区类型符, 有如下特定符
00H H -- 表示该分区未用 ( 即没有指定 ) ;
06H H -- FAT 16 基本分区;
0 0 BH -- FAT 32 基本分区;
05H H -- 扩展分区;
07H H -- NTFS 分区;
0 0 FH -- ( LBA 模式 ) 扩展分区 (83H H 为 Linux)
分出主分区后, 其余的部分可以分成扩展分区, 一般是剩下的部分全部分成扩展分区, 也可以不全分, 剩下的部分就浪费了. 扩展分区不能直接使用, 必须分成若干逻辑分区. 所有的逻辑分区都是扩展分区的一 部分 .
硬盘的容量 = 主分区的容量 + 扩展分区的容量
扩展分区的容量 = 各个逻辑分区的容量之和
3. 启动 Boot Loader
? Linux 的 Boot 的过程
Boot Loader
又叫做 操作系统内核加载器(OS kernel loader), 一个在 kernel 运行前运行的一段小程序, 通过这段程序可以初始化硬件设备, 建立内存空间的映射, 将系统软硬件环境带到一个合适的状态, 便于未来调用操作系统内核.
Linux 下引导加载程序常见两种 https://www.wikiwand.com/zh-hk/LILO 和 GNU GRUB https://www.wikiwand.com/zh/GNU_GRUB
LILO | GRUB |
---|---|
无交互命令界面 | 有交互命令界面 |
不支持网络引导 | 支持 |
错误配置 MBR 会让系统无法引导 | 如果配置文件错误,则默认跳转到 GRUB 命令行界面 |
GRUB 磁盘引导的过程如下
- stage1: grub 读取磁盘第一个 512 字节(硬盘的 0 道 0 面 1 扇区, 被称为 MBR (主引导记录), 也称为 bootsect ). MBR 由一部分 bootloader 的引导代
码, 分区表和魔数三部分组成.( 启动的第二步 )
- Stage1.5: 识别各种不同的文件系统格式. 这使得 grub 识别到文件系统.
- stage2: 加载系统引导菜单 (/boot/grub/ menu.lst 或 grub.lst) ) , 加载内核映像 (kernel image) 和 RAM 磁盘 initrd (可选).
运行主引导程序的具体过程
BIOS 将硬盘主引导记录读入 7C00 处, 并将控制权交给主引导程序:
检查 0x7dfe 地址处是否等于 0xaa55. 不是则去其他介质; 如果没有启动的介质, 显示 "No ROME BASIC" 并死机.
成功找到介质, 跳转到 0X7C00 执行 MBR 的程序
将自己复制到 0x0600 处且继续执行
主分区表中搜索标志为激活的分区, 如果发现没有激活分区或者不止一个激活分区则停止.
将激活分区的第一个扇区读入内存地址 0x7c00
再次检查位于地址 0x7dfe 的内容是否等于 0xaa55, 若不等则停止并尝试软盘启动
跳转到 0x7c00 继续执行特定系统的启动程序
补充: MBR 和引导扇区的关系
MBR 存放的位置是整个硬盘的第一个扇区
Boot Sector 是硬盘上每一个分区的第一个扇区
4. 加载 kernel
主要有两个步骤:
根据 grub 设定的内核映像所在路径 , 系统读取内存映像 , 并进行解压缩操
作 .
系统将解压后的内核放置在内存之中, 初始化函数并初始化各种设备 , 完
成 Linux 核心环境的建立 .
以 Linux 系统为例, 先载入 / boot 目录下面的 kernel.
内核加载成功后, 第一个运行的程序是 / sbin/init. 它根据配置文件 (Debian 系统是 / etc/initab) 产生 init 进程. 这是 Linux 启动后的第一个进程, pid 进程编号为 1, 其他进程都是它的后代.
然后, init 线程加载系统的各个模块, 比如窗口程序和网络程序, 直至执行 / bin/login 程序, 跳出登录界面, 等待用户输入 username 和 password.
至此, 全部启动过程完成.
来源: http://www.bubuko.com/infodetail-2996629.html