启动过程

Penguin, Boot

启动过程概述

Linux的启动过程可以简单分为如下四步:

  • BIOS POST
  • Boot loader
  • Kernel initialization
  • Start systemd, the parent of all processes.

BIOS POST (Basic IO system Power On Self Test)

BIOS是和启动相关的一段重要的程序,为了研究BIOS的功能,我们首先对计算机体系结构进行一个概述

计算机体系结构概述

在计算机中,CPU通过总线与IO设备(硬盘、键盘、鼠标等)和内存相连。当计算机上电后,CPU执行的第一条指令在哪里呢?首先,CPU加电后会对寄存器进行初始化,然后开始执行第一条指令。第一条指令存放在ROM中,ROM是掉电非易失的,所以可以将我们的第一条代码保存在这里。

图片名称

启动时计算机的内存布局

在计算机启动时,内存布局如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
+------------------+  <- 0xFFFFFFFF (4GB)
| 32-bit |
| memory mapped |
| devices |
| |
/\/\/\/\/\/\/\/\/\/\

/\/\/\/\/\/\/\/\/\/\
| |
| Unused |
| |
+------------------+ <- depends on amount of RAM
| |
| |
| Extended Memory |
| |
| |
+------------------+ <- 0x00100000 (1MB)
| BIOS ROM |
+------------------+ <- 0x000F0000 (960KB)
| 16-bit devices, |
| expansion ROMs |
+------------------+ <- 0x000C0000 (768KB)
| VGA Display |
+------------------+ <- 0x000A0000 (640KB)
| |
| Low Memory |
| |
+------------------+ <- 0x00000000

其中,640KB到1MB这一段是系统硬件部分,BIOS写死在960KB开始的地方。CPU启动后处于实模式,第一条指令位于CS:IP=0xf000:fff0的位置,即BIOS ROM的区域。此时只有20位地址(1MB)可用。

BIOS提供的服务

  • 基本输入输出(从硬盘、键盘输入输出等)
  • 系统设置信息
  • 开机自检程序
  • 系统自启动程序

进入BIOS程序后,将BootLoader从磁盘加载至0x7c00,并跳转。载入Boot Loader后的内存如下

1
2
3
4
5
6
7
8
9
10
11
12
+------------------+  <- 0x00100000 (1MB)
| BIOS ROM |
+------------------+ <- 0x000F0000 (960KB)
| 16-bit devices, |
| expansion ROMs |
+------------------+ <- 0x000C0000 (768KB)
| VGA Display |
+------------------+ <- 0x000A0000 (640KB)
| |
| Boot Loader | <- 0x00007C00
| BIOS DATA |
+------------------+ <- 0x00000000

BIOS 基本IO功能

以下功能只能在实模式下使用

  • INT 10h:字符显示
  • INT 13h:磁盘扇区读写
  • INT 15h:内存大小检测
  • INT 16h:键盘输入

BIOS 过程

为什么不让BIOS直接加载?

因为各种文件系统是不同的,不可能让一个BIOS包含所有的文件系统的读取,因此只让BIOS从硬盘固定区域进行读写

UEFI

UEFI的目标是在所有平台上一致的操作系统启动服务,实际是一个接口标准。

Boot Loader

Boot Loader 负责将操作系统代码数据加载至内存,然后跳转至起始地址

Linux Boot Loader 过程

GRUB2

GRUB2全称为GRand Unified Bootloader, version 2,是现今主流Linux普遍采用的Boot Loader。其基本功能是找到linux内核,然后载入到内存中并运行。

第一阶段

在POST结束时,BIOS会寻找到第一个Boot分区,加载bootstrap code,即GRUB2 Stage 1,这段代码非常小,因为必须适配前512字节的扇区(统一规定)。因为这个代码太小了,做不到太多有意义的工作,唯一的目的是定位下一个阶段并进行跳转

第1.5阶段

GRUB2 的1.5阶段位于boot record和第一块硬盘分区之间,这一段空间因为一些原因没有被使用。这一段有62 512-byte的空间存放core.img文件,这个文件的大小是25,389 Bytes,足够放下一些文件系统的驱动,例如标准EXT、FAT及NTFS等。这意味着GRUB第二阶段可以位于标准的EXT文件系统内。第二阶段实际位于/boot下,即/boot/grub2。

第2阶段

第二阶段位于/boot/grub2和其子文件夹下,它将运行期内核模块放置在了/boot/grub2/i386-pc文件夹下。第2阶段的作用是定位并载入所选择的Linux内核,内核和相关文件在/boot文件夹下。

Kernel

所有的kernel都经过了压缩并可自解压,从而节省空间,kernel和初始的RAM镜像以及设备映射位于/boot文件夹下。当内核被载入后,它会进行自解压,并载入systemd,并将控制权移交。至此,Boot阶段结束。

启动阶段

systemd

systemd是所有进程的父进程,它将会使linux正式进入可工作状态。systemd将会完成如下工作:

  • 挂载由/etc/fstab定义的文件系统,从而可以获取/etc下的配置文件

实模式VS保护模式

实模式

地址表示

在实模式下,CPU通过直接访问实际的物理地址对内存进行访问,此时地址格式为[CS:IP],物理地址为:

保护模式

在保护模式下,segment_part由一个16位的选择器代替,高13位为描述表的入口;而第2位表示使用GDT或LDT,最低两位表示优先级,0-3分别代表最高优先级和最低优先级

参考文献

0%