摘要
引导 Linux 系统涉及不同组件。BIOS 初始化硬件本身,并通过引导加载程序启动内核。之后,init 的引导进程及运行级别将完全受操作系统控制。runlevel 概念使您可以维护日常使用的设置,也可以对系统执行维护任务。
Linux 引导进程包括多个阶段,每个阶段由一个不同组件来代表。下表概要总结了引导进程并介绍了所涉及的所有主要组件。
BIOS. 在打开计算机之后,BIOS 将初始化屏幕和键盘并测试主内存。直到这一阶段,计算机不访问任何大容量储存媒体。随后,将从 CMOS 值装载有关当前日期、时间和最重要的外设的信息。当识别出第一块硬盘及其空间之后,系统控制将从 BIOS 传递到引导加载程序。
引导加载程序. 第一块硬盘的前 512 个字节的物理数据扇区将被装载到主储存器中,位于此扇区开始位置的引导加载程序将接管系统控制。引导加载程序执行的命令决定了引导进程剩余的部分。因此,第一块硬盘的前 512 个字节被称为主引导记录 (MBR)。引导加载程序随后将控制权交给实际的操作系统(在本例中即 Linux 内核)。有关 Linux 引导加载程序 GRUB 的详细信息,请参见第 10 章 引导加载程序 GRUB。
内核和 initramfs.
为了交接系统控制权,引导加载程序将内核和基于 RAM 的初始文件系统 (initramfs) 装载到内存中。内核可以直接使用 initramfs 的内容。initramfs 包含一个小的可执行文件,称为 init,可以处理真实 root 文件系统的装入。如果需要特殊硬盘驱动程序才能访问大容量储存,则这些程序必须在 initramfs 中。有关 initramfs 的详细信息,请参见第 9.1.1 节 “initramfs”。
initramfs 中的 init.
此程序执行装入正确 root 文件系统所需的所有操作,如为所需的文件系统提供内核功能以及为带有 udev 的大容量储存控制器提供设备驱动程序。找到 root 文件系统后,对其进行错误检查并装入。如果此操作成功,将清除 initramfs 并执行 root 文件系统上的 init 程序。有关 init 的详细信息,请参见第 9.1.2 节 “initramfs 上的 init”。有关 udev 的详细信息,请参见第 13 章 使用 udev 进行动态内核设备管理。
init.
init 通过提供不同功能的多个不同级别来处理实际的系统引导。有关 init 的介绍,请参见第 9.2 节 “init 进程”。
initramfs¶
initramfs 是一个内核可以装载到 RAM 磁盘的小型 cpio 归档。它提供了一个最小的 Linux 环境,可在装入实际 root 文件系统之前执行程序。这个最小的 Linux 环境由 BIOS 例程装载进内存,而且除了需要足够的内存外没有特别的硬件要求。initramfs 必须始终提供一个名为 init 的可执行文件,该文件应该执行 root 文件系统中实际的 init 程序以使引导进程继续进行。
在能够装入 root 文件系统并启动操作系统之前,内核需要相应的驱动程序来访问 root 文件系统所在的设备。这些驱动程序可能包括用于特定类型硬盘的特殊驱动程序,甚至还可能包括访问网络文件系统所需的网络驱动程序。root 文件系统所需的模块可以由 initramfs 上的 init 来装载。装载模块后,udev 将为 initramfs 提供所需的设备。在引导过程的后面,更改 root 文件系统之后需要重新生成设备。通过 boot.udev(使用 udevtrigger 命令)来完成此操作。
如果需要更改已安装系统的硬件(例如硬盘),并且该硬件要求引导时内核中有不同的驱动程序,则必须更新 initramfs。操作方法和其前身 init 一样,即调用 mkinitrd。调用 mkinitrd(不带任何参数)创建 initramfs。调用 mkinitrd -R 创建 init。在 SUSE® Linux Enterprise Desktop 中,要装载的模块由 /etc/sysconfig/kernel 中的变量 INITRD_MODULES 指定。安装后,自动将此变量设置为正确的值。将严格按照这些模块在 INITRD_MODULES 中出现的顺序来装载它们。只有您依赖正确的设备文件 /dev/sd? 设置时,这才显得重要。然而,在当前系统下,也可以使用 /dev/disk/ 下的设备文件。这些文件以几个子目录的形式排序,分别为 by-id、by-path 和 by-uuid,并始终代表相同的磁盘。也可以在安装时通过指定相应的装入选项完成此操作。
![]() | 更新 initramfs 或 init |
|---|---|
引导加载程序装载 | |
initramfs 上的 init¶
initramfs 上的 init 的主要用途是准备真实 root 文件系统的装入和访问。init 负责以下任务,具体取决于您的系统配置。
根据硬件配置的不同,可能需要一些特殊的驱动程序来访问计算机的硬件组件(最重要的组件是硬盘)。要访问最终的 root 文件系统,内核需要装载正确的文件系统驱动程序。
内核对每个装载的模块生成设备事件。udev 会处理这些事件并在 RAM 文件系统的 /dev 中生成所需的特殊块文件。没有这些特殊文件,文件系统和其他设备将不可访问。
如果将系统配置为在 RAID 或 LVM 下保存 root 文件系统,则 init 将设置 LVM 或 RAID 以支持稍后对 root 文件系统的访问。在第 12 章 Advanced Disk Setup (↑部署指南)中查找关于 RAID 和 LVM 的信息。
如果将系统配置为使用通过网络装入的 root 文件系统(通过 NFS 装入),则 init 必须确保装载了正确的网络驱动程序,并确保将其设置为支持访问 root 文件系统。
在初始引导期间作为安装过程的一部分调用 init 时,要执行的任务将与上述任务不同:
启动安装进程时,计算机将通过安装媒体中的 YaST 安装程序装载一个安装内核和一个特殊的 init。YaST 安装程序在 RAM 文件系统中运行,它需要有关安装媒体位置的信息以访问安装媒体并安装操作系统。
如第 9.1.1 节 “initramfs” 中所述,引导进程从可用于大多数硬件配置的一组最小的驱动程序开始。init 将启动初始硬件扫描进程,以确定适合您的硬件配置的一组驱动程序。引导进程所需的模块名写进 /etc/sysconfig/kernel 中的 INITRD_MODULES。这些名称用于生成引导系统所需的自定义 initramfs。如果模块不是用于引导,而是用于冷插入,则模块要写进 /etc/sysconfig/hardware/hwconfig-*。本目录下用配置文件描述的所有设备均要在引导过程中进行初始化。
正确识别硬件后,便会装载合适的驱动程序,udev 将创建特殊的设备文件,init 将使用实际 YaST 安装程序启动安装系统或者救援系统。
最后,init 将启动 YaST,由后者启动包安装和系统配置。
init 进程¶
init 程序是进程 ID 为 1 的进程,负责按所要求的方式初始化系统。init 由内核直接启动,并且抵制信号 9(该信号通常会终止进程)。所有其他程序由 init 直接启动,或由它的其中一个子进程启动。
init 在 /etc/inittab 文件中集中配置,其中运行级别已定义(请参见第 9.2.1 节 “运行级别”)。该文件还指定了在每个运行级别有哪些服务和守护程序可用。根据 /etc/inittab 中的项,init 将运行若干个脚本。默认情况下,引导后启动的第一个脚本为 /etc/init.d/boot。完成系统初始化阶段后,系统将使用 /etc/init.d/rc 脚本把运行级别更改为默认运行级别。为了清楚起见,这些称作 init 脚本的脚本都位于目录 /etc/init.d 中(请参见第 9.2.2 节 “Init 脚本”)。
启动和关闭系统的整个过程是由 init 维护的。从这一点来看,可以将内核视为一个后台进程,其任务是维护所有其他进程,以及根据其他程序的请求来调整 CPU 时间和硬件访问。
在 Linux 中,运行级别定义了系统如何启动以及正在运行的系统中有哪些服务可用。在引导后,系统会按照 /etc/inittab 中的 initdefault 行所定义的方式启动。通常是 3 或 5。请参见表 9.1 “可用运行级别”。也可以选择在引导时指定运行级别(例如,在引导提示符后添加运行级别号)。不直接由内核本身评估的任何参数均将传递给 init。要引导到 runlevel 3,只需向引导提示符添加一个数字 3。
表 9.1. 可用运行级别¶
|
运行级别 |
描述 |
|---|---|
|
0 |
系统暂停 |
|
S 或 1 |
单用户方式 |
|
2 |
没有远程网络的本地多用户方式(NFS 等) |
|
3 |
有网络的完全多用户方式 |
|
4 |
除非管理员配置该运行级别,否则不使用。 |
|
5 |
有网络和 X 显示管理器的完全多用户方式 - KDM、GDM 或 XDM |
|
6 |
系统重引导 |
![]() | 避免运行级别 2 与通过 NFS 装入的分区 |
|---|---|
如果您的系统通过 NFS 装入了 | |
要在系统运行时更改运行级别,请输入 telinit 和作为参数的相应数字。仅允许系统管理员执行该操作。下表总结了运行级别区域中最重要的命令。
系统更改为单用户方式。该方式用于系统维护和管理任务。
启动了所有基本的程序和服务(包括网络),允许普通用户登录并在不具备图形环境的系统中工作。
启用了图形化环境。通常启动诸如 XDM、GDM 或 KDM 之类的显示管理器。如果启用 autologin,则本地用户便可登录到预先选择的窗口管理器(GNOME 或 KDE 或其他任何窗口管理器)中。
系统暂停。
系统暂停后重引导。
运行级别 5 是所有 SUSE Linux Enterprise Desktop 标准安装中的默认运行级别。提示用户使用图形界面登录,或者默认用户将自动登录。
![]() | /etc/inittab 中的错误可能导致系统引导出现故障 |
|---|---|
如果 | |
通常情况下,更改运行级别时会发生两件事情。首先是启动当前运行级别的停止脚本,同时关闭当前运行级别必需的一些程序。然后启动新运行级别的启动脚本。在大多数情况下,这时会启动多个程序。例如,将运行级别从 3 更改到 5 时会发生以下情况:
通过输入 telinit 5,管理员 (root) 请求 init 更改到其他运行级别。
init 检查当前运行级别 (runlevel) 并确定是否应使用新的运行级别作为参数来启动 /etc/init.d/rc。
rc 现在调用当前运行级别的停止脚本,但仅限新运行级别中没有启动脚本的那些停止脚本。在本例中,这些就是位于 /etc/init.d/rc3.d(旧的运行级别是 3)中以 K 开头的所有脚本。K 后跟的编号指定使用 stop 参数运行脚本的顺序,因为有很多依赖性要考虑。
最后要启动的是新运行级别的启动脚本。在本例中,这些是位于 /etc/init.d/rc5.d 中以 S 开头的脚本。S 后跟的编号确定启动脚本的顺序。
当更改为与当前运行级别相同的运行级别时,init 仅检查 /etc/inittab 的更改,并启动相应的步骤(例如,在另一个界面上启动 getty 所需的步骤)。使用命令 telinit q 也达到到相同的作用。
/etc/init.d 中有两种类型的脚本:
所有脚本位于 /etc/init.d 中。引导时运行的脚本是通过指向 /etc/init.d/boot.d 的符号链接调用的。用于更改运行级别的脚本也是通过符号链接从一个子目录(/etc/init.d/rc0.d 到 /etc/init.d/rc6.d)进行调用的。这仅仅是为了清楚起见,并避免在多个运行级别中使用时出现重复脚本。因为每个脚本既可以作为启动脚本也可以作为停止脚本来执行,这些脚本必须理解 start 和 stop 参数。这些脚本还必须理解 restart、reload、force-reload 和 status 选项。对这些不同的选项进行了解释。表 9.2 “可能的 init 脚本选项” 由 init 直接运行的脚本没有这些链接。需要时,可以从运行级别独立运行它们。
表 9.2. 可能的 init 脚本选项¶
|
选项 |
描述 |
|---|---|
|
|
启动服务。 |
|
|
停止服务。 |
|
|
如果服务正在运行,则首先将其停止,然后重启动。如果服务未在运行,则启动服务。 |
|
|
在不停止和重启动服务的情况下重装载配置。 |
|
|
如果服务支持,则重装载配置。否则,要执行的步骤与指定 |
|
|
显示服务的当前状态。 |
每个特定于运行级别的子目录中的链接使将脚本与不同的运行级别相关联成为可能。在安装或卸载包时,在程序 insserv(或使用 /usr/lib/lsb/install_initd,它是调用此程序的一个脚本)的帮助下可添加和删除这些链接。有关更多细节,请参见 man 8 insserv。
所有这些设置也可能在 YaST 模块的帮助下发生变化。如果需要在命令行上检查状态,请使用 man 8 chkconfig 手册页中所描述的工具 chkconfig。
下面分别简要介绍最先或最后启动的引导和停止脚本,并对脚本的维护进行了描述。
boot
在使用 init 直接启动系统时执行。它与选择的运行级别无关,而且仅执行一次。这时将装入 /proc 和 /dev/pts 文件系统,并激活 blogd(引导日志记录守护程序)。如果在更新或安装后首次引导系统,则会启动初始系统配置。
blogd 守护程序是由 boot 和 rc 启动的第一个服务。它在由这些脚本触发的操作(运行几个子脚本,例如使特殊块文件变为可用的)完成之后停止。blogd 将所有屏幕输出写入日志文件 /var/log/boot.msg(前提是装入的 /var 是可读写的)。否则,blogd 将缓冲所有屏幕数据,直到 /var 可用。有关 blogd 的进一步信息,请使用 man 8 blogd。
boot 脚本还负责启动 /etc/init.d/boot.d 中名称以 S 开头的所有脚本。在这里,将检查文件系统并根据需要配置回路设备。同时设置系统时间。如果在自动检查和修复文件系统时出错,系统管理员可以在输入根密码后进行干预。上次执行的脚本是 boot.local。
boot.local
halt
此脚本仅在更改为运行级别 0 或 6 时执行。在这里,它作为 init 或 init 来执行。是关闭还是重引导系统取决于调用 halt 的方式。如果在关闭系统过程中需要特殊命令,请将此类命令添加到 init 脚本。
rc
此脚本调用当前运行级别的相应停止脚本和新选择的运行级别的启动脚本。与 /etc/init.d/boot 脚本类似,该脚本是通过将所需运行级别用作参数从 /etc/inittab 调用的。
您可以创建自己的脚本并方便地将它们集成到上面描述的方案中。有关格式化、命名和组织自定义脚本的说明,请参考 LSB 的规范以及 init、init.d、chkconfig 和 insserv 的手册页。此外还可以参见 startproc 和 killproc 的手册页。
![]() | 有问题的 init 脚本可能会使您的系统暂停 |
|---|---|
有问题的 | |
要为给定程序或服务创建自定义 init 脚本,请使用文件 /etc/init.d/skeleton 作为模板。以新名称保存此文件的副本,然后根据需要编辑相关程序和文件名、路径及其他细节。您可能还需要用自己的部分来增强此脚本,以便 init 过程可以触发正确的操作。
位于顶部的 INIT INFO 块是脚本的一个必需部分,应进行编辑。请参见例 9.1 “最小的 INIT INFO 块”。
例 9.1. 最小的 INIT INFO 块¶
### BEGIN INIT INFO # Provides: FOO # Required-Start: $syslog $remote_fs # Required-Stop: $syslog $remote_fs # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Description: Start FOO to allow XY and provide YZ ### END INIT INFO
在 INFO 块第一行上 Provides: 后,指定由此 init 脚本控制的程序或服务的名称。在 Required-Start: 和 Required-Stop: 行中,指定停止服务本身时仍需运行的所有服务。这些信息稍后用于生成脚本名的编号(可以在运行级别目录中找到)。在 Default-Start: 和 Default-Stop: 后,指定应自动启动或停止的服务所在的运行级别。最后,在 Description: 下,提供对相关服务的简短描述。
要创建从运行级别目录 (/etc/init.d/rc?.d/) 到 /etc/init.d/ 中相应脚本的链接,请输入命令 insserv new-script-name。insserv 对 INIT INFO 标题进行评估,以便为运行级别目录 (/etc/init.d/rc?.d/) 中的启动和停止脚本创建所需的链接。此程序还负责保证每个运行级别的启动和停止顺序正确无误,方法是在这些链接的名称中包含必要的数字。如果要使用图形工具来创建这样的链接,请按照第 9.2.3 节 “使用 YaST 配置系统服务(运行级别)”中描述的方法使用 YaST 提供的运行级别编辑器。
如果应将已存在于 /etc/init.d/ 中的脚本集成到现有运行级别方案中,请立即通过 insserv 或启用 YaST 的运行级别编辑器中的相应服务在运行级别目录中创建链接。您的更改将在下次重引导时生效 - 新服务将自动启动。
不要手动设置这些链接。如果 INFO 块中出错,则在稍后为其他服务运行 insserv 时将会出现问题。下次为此脚本运行 insserv 时将删除手动添加的服务。
使用 ++启动此 YaST 模块后,它将显示一个概要,列出所有可用的服务和每个服务的当前状态(禁用或启用)。确定是以还是以使用此模块。默认的足以完成大多数操作。左边的列显示服务的名称,中间的列指示其当前状态,而右边的列则给出简短描述。窗口下部提供了对所选服务的更为详细的描述。若要启用某个服务,请首先在表中选定它,然后选择。同样的步骤可用于禁用服务。
要对所启动或停止的服务所在运行级别进行更具体的控制,或者更改默认运行级别,请先选择。将在顶部显示当前默认的运行级别或 “initdefault”(默认情况下将系统引导至的运行级别)。通常情况下,SUSE Linux Enterprise Desktop 系统的默认运行级别是运行级别 5(有网络和 X 的完全多用户模式)。运行级别 3(有网络的完全多用户方式)是合适的替代选择。
此 YaST 对话框用于选择一个运行级别(如表 9.1 “可用运行级别” 中所列)作为新的默认运行级别。此外,可使用此窗口中的表来启用或禁用各个服务和守护程序。此表列出可用的服务和守护程序,显示它们当前是否已在您的系统上启用,如果已启用,则指示它们用于哪些运行级别。用鼠标选择其中的一行后,请单击表示运行级别(、、、、、、 和 )的复选框来确定所选服务或守护程序的运行级别。未对运行级别 4 进行定义,目的是供用户创建自定义运行级别。表概要下方提供了当前所选服务或守护程序的简要描述。
![]() | 有问题的运行级别设置可能会对您的系统造成损害 |
|---|---|
有问题的运行级别设置可能会导致系统无法使用。在应用您的更改之前,请确保您清楚这些设置可能产生的结果。 | |
用来确定是否应激活某服务。用来检查当前状态。用于选择是将更改应用到系统,还是恢复启动运行级别编辑器之前存在的设置。选择即可将已更改的设置保存到磁盘。
/etc/sysconfig 配置系统¶
SUSE Linux Enterprise Desktop 的主要配置是由 /etc/sysconfig 中的配置文件控制的。只有与 /etc/sysconfig 中的各个文件相关的脚本才会读取它们。这样有很多好处,例如确保了网络设置只需要由与网络相关的脚本来分析。
可以使用两种方法编辑系统配置。使用 YaST sysconfig 编辑器或手动编辑配置文件。
YaST sysconfig 编辑器为系统配置提供了一种易于使用的前端。无需了解需要更改的配置变量的实际位置,只需使用此模块的内置搜索功能,就可以按需更改配置变量的值,并使 YaST 负责应用这些更改以及根据 sysconfig 中设置的值更新配置和重启动服务。
![]() | 修改 /etc/sysconfig/* 文件可能会对您的安装造成损害 |
|---|---|
如果没有足够的经验和知识,切勿修改 | |
YaST sysconfig 对话框分为三个部分。对话框左边的部分显示了一个树视图,其中列出了所有可配置变量。当您选择某个变量时,右边的部分会显示当前选择和此变量的当前设置。在下面第三个窗口中,简要描述了变量的用途、可能的值、默认值以及此变量源自的实际配置文件。此对话框还提供了有关更改变量后将执行哪些配置脚本,以及作为更改的结果将启动哪些新服务等信息。YaST 将提示您确认更改,并通知您在选择退出对话框后将执行哪些脚本。在这里还可以选择需要现在跳过而在以后启动的服务和脚本。YaST 将自动应用所有的更改并重启动涉及的所有服务以使更改生效。
要手动更改系统配置,请执行如下操作
成为 root。
使用 telinit 1 将系统转入单用户模式(运行级别 1)。
使用您选择的编辑器根据需要对配置文件进行更改。
如果不使用 YaST 来更改 /etc/sysconfig 中的配置文件,则要确保将空变量值用两个引号表示 (KEYTABLE=""),并将含有空白的值用引号括起来。只包括一个单词的值不需要用引号括起来。
执行 SUSEconfig 来确保更改生效。
使用类似 telinit default_runlevel 的命令将系统返回到先前的运行级别。使用系统的默认运行级别替代 default_runlevel。如果想返回 有网络和 X 的完全多用户方式,请选择 5;如果希望在有网络的完全多用户方式下工作,请选择 3。
这一过程主要用于更改整个系统范围的配置,例如网络配置。若要进行较小的更改,不一定要切换到单用户方式,但这样做可以完全确保正确重启动所有相关的程序。
![]() | 配置自动系统配置 |
|---|---|
要禁用 SuSEconfig 设定的自动系统配置,请将 | |