summaryrefslogtreecommitdiff
path: root/06_boot_process.rst
blob: 00edb74b105b32aea80d52de50c5c41aec5d346e (plain)
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
计算机系统的启动过程
======================

本章内容来自 https://github.com/mytbk/Linux_Notes/blob/master/install/from-firmware-to-userspace.md

在一个使用 systemd 的系统中执行 systemd-analyze, 会得到如下形式的输出::

  $ systemd-analyze

  Startup finished in 3.222s (firmware) + 6.642s (loader) + 2.101s (kernel) + 1.734s (userspace) = 13.700s

可以看出,系统的启动分为4个部分,固件(firmware),引导加载器(bootloader),内核(kernel),用户空间(userspace).我们就把从机器上电开机开始的4个过程一个一个地描述出来。

固件(firmware)
----------------

计算机启动后,首先会从ROM中执行一段程序,这段程序就是固件。固件的作用是完成硬件的初始化和检测,提供访问硬件的接口,最后加载引导加载器或者操作系统内核。

我们在这里主要讨论固件是怎么引导系统的。不同的固件用不同的方式引导系统,x86平台上常用的固件有BIOS和UEFI.

BIOS(basic input/output system)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BIOS起源于IBM PC,并一直沿用到现在。BIOS引导系统的过程如下:

1. 读取引导设备(硬盘,软盘,U盘等)的第一个扇区到内存的指定地址0000:7C00.

2. 检查这个扇区的最后两个字节是否为0x55 0xaa(小端表示为0xaa55),如果是,则进行下一步,否则回到第1步。

3. 跳转到0000:7c00执行引导代码。

UEFI(Unified Extensible Firmware Interface)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`UEFI <http://www.uefi.org/>`__ 是Intel提出的固件结构,起初用于Intel的IA64平台,后来移植到了x86和x86_64平台,同时也有ARM设备使用UEFI.

UEFI规范中指定了UEFI固件的结构,编程规范,也规定了引导系统的方式。UEFI固件引导系统的过程如下:

1. 读取启动设备的EFI系统分区(一般是第一个分区,使用FAT32文件系统),寻找启动文件(默认为efi/boot/bootx64.efi).

2. 执行启动文件,完成引导。


引导加载器(bootloader)
---------------------------

有了固件标准之后,程序员根据固件引导系统的方式,写了相应的能被固件使用的引导加载器。引导加载器的作用是加载并启动操作系统的内核。操作系统的类型很多,内核的启动也有很多参数,引导加载器可以根据用户的配置,使用合适的参数启动内核。很多引导加载器有多系统引导,命令行界面等功能。

用于引导Linux的常用引导加载器有GRUB,syslinux等。


内核(kernel)
--------------------

内核是操作系统的核心部件,向下管理硬件资源,向上为应用程序提供服务。Linux是一个内核,它实现了内存管理,进程调度等操作系统的基本功能,还包含了很多硬件驱动程序。Linux内核进行了一系列的初始化操作之后,会启动第一个进程,称为init.


用户空间(userspace)
----------------------

init进程的作用是启动其他进程,从而操作系统就启动了很多的应用程序,包括图形界面,网络服务等。默认情况下,Linux启动/sbin/init作为init进程,但可以通过修改内核的init参数选择其他的init程序。常用的init程序有sysvinit,systemd,busybox init等。