LFS101x.2 Introduction to Linux (Linux Foundation)
Chapter 03: Linux Structure and Installation - Section 2: The Boot Process
你是否想过,在你按下电源开关直至Linux登陆提示出现时,后台到底发生了哪些事?
Linux的引导过程是系统初始化的过程。它包含了第一次打开计算机直至用户界面完全运作之间的一切。
一旦你开始使用Linux,你会发现,深入理解系统的引导流程,可以帮助你快速诊断故障,同时也可以帮助你调整计算机性能以满足你的要求。
启动一台基于x86的Linux系统包含很多步骤。当计算机开机后,基本输入输出系统(Basic Input/Output System,BIOS)会初始化硬件,例如显示屏、键盘等等,并且测试主存储器。这个步骤被称为上电自检(Power On Self Test,POST)。
BIOS软件被存储在主板的一块ROM芯片中。在这个步骤之后,剩余的引导流程将会交给操作系统完成。
一旦完成上电自检(POST),系统的控制权由BIOS转给引导加载程序(boot loader)。引导加载程序通常存储在系统的其中一个硬盘中,要么在启动扇区(boot sector,对于传统的BIOS/MBR系统)中,要么在EFI分区(EFI partition,对于最近标准的可扩展固件接口,或称为EFI/UEFI系统)中。到这个阶段,机器还不能访问任何大规模存储设备。然后,日期、时间等信息,以及重要的外围设备从CMOS(一项基于电池供电的存储技术,保证系统掉电后仍可以记录日期和时间)中加载至系统。
有许多种适用于Linux的引导加载程序;最常见的是GRUB(用于统一引导加载程序)和ISOLINUX(用于从移动设备中启动)。大多数的Linux引导程序可以提供一个用户界面,用于选择Linux的可选引导项,甚至可以选择其他已安装的操作系统。当引导Linux之时,引导加载程序负责加载内核镜像(kernel image)以及初始RAM磁盘(initial RAM disk,包含一些关键文件和启动系统所需的驱动程序)到内存中。
引导加载程序包含两个不同的阶段:
对于使用BIOS/MBR方式的系统,引导加载程序存放在硬盘的第一个扇区,也被成为主引导记录(Master Boot Record,MBR)。MBR的大小仅仅512字节。在这个阶段,引导加载程序检查分区表,并找到一个可引导分区。一旦它找到了可引导分区,它将搜索第二阶段的引导加载程序,例如GRUB,并且将它加载到随机存储器(Random Access Memory,RAM)中。
对于使用EFI/UEFI方式的系统,UEFI固件读取引导管理器(Boot Manager)数据,以决定哪个UEFI应用启动且从哪启动(从哪个磁盘和分区可以找到EFI分区)。然后这个固件启动这个UEFI应用,例如GRUB,这个UEFI应用被定义为固件引导管理器的引导入口。这个过程更为复杂,但是比以往MBR方式更为灵活。
第二阶段的引导加载程序位于 /boot 目录下。一个显示画面会出现,让我们选择引导哪个操作系统(Operating System,OS)。在选择完OS之后,引导加载程序加载选定操作系统的内核到RAM,然后将控制权交给它。
引导程序加载了选定的内核镜像(如果是Linux)并将控制权给它之后。内核几乎总是被压缩的,所以它的第一件事就是解压内核文件。然后,它会检查并分析系统硬件,并初始化内核中存在的所有硬件设备驱动。
引导程序将内核和一个基于RAM的初始文件系统(initramfs)加载到内存,使得initramfs可以被内核直接使用。
当内核在RAM中加载完毕,它会立刻初始化并配置计算机内存,同时也配置所有的系统硬件。这包括所有的处理器、I/O子系统、存储设备等等。内核同时也加载一些必要的用户空间程序。
initramfs文件系统镜像包含程序文件和二进制文件,这些文件可以完成挂载root文件系统所需的所有操作。比如,给所需的文件系统提供内核功能,给大容量存储控制器提供设备驱动udev(为用户设备),这些驱动负责找出哪些设备可用,定位这些设备正常工作所需的驱动,并且加载它们。当找到root文件系统之后,检测是否有错,并挂载文件系统。
挂载(mount)程序会指示操作系统,文件系统已经可用,并将文件系统全局层次的一个特定点与之关联,这个点称为挂载点(themount point)。如果操作成功,initramfs将会从RAM中清除,然后root文件系统下(/sbin/init)的init程序将会执行。
init程序处理挂载和跳转到最终实际的root文件系统。如果在大容量存储器可以访问之前,需要一些特殊的硬件驱动,这些驱动必须包含在initramfs镜像中。
一旦内核设置完所有的硬件并挂载root文件系统,内核执行 /sbin/init程序。然后,这变成了初始化进程,然后开始其他进程以使得系统运转。大多数系统上的进程,追其来源,都来自与init;例外的是内核进程,内核进程直接由内核启动,管理操作系统的内部细节。
传统上,这个进程启动所使用的约定,可以追溯到System V UNIX时期,系统运行是通过一系列的运行等级(runlevel)和一系列启动/停止服务的脚本来完成的。每个运行等级支持运行系统的不同模式。在每个运行等级,个人服务可以设置开始运行,或者停止运行。更新的发行版本抛弃了System V约定,但是通常为了兼容性仍支持System V约定。
除了启动系统,init还要负责保持系统运行或完全关闭系统。它扮演了所有非内核进程“最终管理者”的角色。当必要时会在进程结束后清理它们,当用户需要登陆/登出时会重启用户登录服务。
在引导进程接近结束之时,init启动了一系列文本模式登陆提示(通过一个叫做getty的程序)。这使得你能够输入自己的用户名,密码,并最终进入命令shell界面。
通常,这个命令shell叫做bash(the GNUBourne Again Shell),但是也存在很多其他高级的命令shell可用。shell会打印出一个文本提示,表明已经准备好接受命令;当用户输入命令并敲击Enter键之后,命令会被执行,然后另一个文本提示会在命令执行后显示。
就如你在Command Line Operations章节所学到的那样,运行命令shell的终端可以通过ALT加功能键(functionkey)访问。大多数发行版本从F1或者F2开始,开启6个文本终端和一个图形终端。如果图形终端也启动了,那么切换至文本终端需要按CTRL+ALT再加上相应的功能键(F1或者F7是GUI)。如你接下来将简要看到的,如果你在一个纯文本模式,想要打开或重启图形桌面,需要运行startx命令。
通常,在Linux桌面系统中,加载X Window System是引导进程的最后一步。
一个叫做显示管理器(display manager)的服务会被提供,用于保持显示追踪,并加载X Server(之所以这么叫它,是因为它给应用程序提供图形服务,有时也称为X clients)。这个显示管理器也负责图形登陆,在用户登录后打开特定的桌面环境。
一个桌面环境包括会话管理器(session manager,启动并保持图形会话组件),窗口管理器(the window manager,控制窗口、窗口标题栏、控制栏的放置和移动)。
尽管可以被混合,通常一系列工具、会话管理器和窗口管理器是作为一个整体使用,一起提供一个无缝的桌面环境。
如果显示管理器并不是以默认的运行等级启动,你可以以一种不同的方式启动X:在登陆进入文本模式终端后,通过在命令行运行startx命令开启X。