4.2. 启动过程、Init 和关机

4.2.1. 简介

Linux 最强大的方面之一在于其开放的操作系统启动和停止方法,它加载指定的程序及其特定的配置,允许您更改这些配置以控制启动过程,并以优雅和有组织的方式关机。

除了控制启动或关机过程的问题之外,Linux 的开放性使其更容易确定与启动或关闭系统相关的大多数问题的确切来源。 对此过程的基本理解对于每个使用 Linux 系统的人都非常有益。

许多 Linux 系统使用 lilo,即 LInux LOader 来启动操作系统。 但是,我们只会讨论 GRUB,因为它更易于使用且更灵活。 如果您需要有关 lilo 的信息,请参阅手册页和 HOWTO。 这两个系统都支持双启动安装,关于实际示例和背景信息,我们请您参考 HOWTO。

4.2.2. 启动过程

当 x86 计算机启动时,处理器会在系统内存的末尾查找 BIOS(基本输入/输出系统)并运行它。 BIOS 程序被写入永久只读存储器,并且始终可用。 BIOS 为外围设备提供最低级别的接口,并控制启动过程的第一步。

BIOS 测试系统,查找并检查外围设备,然后查找用于启动系统的驱动器。 通常,它会检查软盘驱动器(或许多较新系统上的 CD-ROM 驱动器)是否存在可启动介质,如果存在,则查找硬盘驱动器。 用于启动的驱动器顺序通常由系统上的特定 BIOS 设置控制。 一旦 Linux 安装在系统的硬盘驱动器上,BIOS 就会在第一个硬盘驱动器的第一个扇区查找主引导记录 (MBR),将其内容加载到内存中,然后将控制权传递给它。

此 MBR 包含有关如何使用预选的操作系统加载 GRUB(或 LILO)引导加载程序的说明。 然后 MBR 加载引导加载程序,该加载程序接管该过程(如果引导加载程序安装在 MBR 中)。 在默认 Red Hat Linux 配置中,GRUB 使用 MBR 中的设置在菜单中显示启动选项。 一旦 GRUB 从其命令行或配置文件收到要启动的操作系统的正确指令,它就会找到必要的启动文件并将机器的控制权交给该操作系统。

4.2.3. GRUB 功能

此启动方法称为直接加载,因为指令用于直接加载操作系统,引导加载程序和操作系统的主文件(例如内核)之间没有中间代码。 但是,其他操作系统使用的启动过程可能与上述略有不同。 例如,Microsoft 的 DOS 和 Windows 操作系统在安装时会完全覆盖 MBR 上的任何内容,而不会合并当前 MBR 的任何配置。 这会破坏其他操作系统(例如 Linux)存储在 MBR 中的任何其他信息。 Microsoft 操作系统以及各种其他专有操作系统都是使用链式加载启动方法加载的。 使用此方法,MBR 指向保存操作系统的分区的第一个扇区,在那里它可以找到实际启动该操作系统所需的特殊文件。

GRUB 支持这两种启动方法,允许您将其与几乎任何操作系统、最流行的文件系统以及几乎任何 BIOS 可以识别的硬盘一起使用。

GRUB 包含许多其他功能; 最重要的包括

有关 GRUB 的完整说明,可以通过发出 info grub 命令或访问 GRUB 站点找到。 Linux 文档项目有一个 使用 GRUB Mini-HOWTO 进行多重启动

4.2.4. Init

内核一旦加载,就会在sbin中找到 init 并执行它。

init 启动时,它将成为 Linux 系统上自动启动的所有进程的父进程或祖父进程。 init 所做的第一件事是读取其初始化文件,/etc/inittab。 这指示 init 读取环境的初始配置文件,该文件设置路径、启动交换、检查文件系统等等。 基本上,此步骤负责处理系统在系统初始化时需要完成的所有事情:设置时钟、初始化串行端口等等。

然后 init 继续读取/etc/inittab文件,该文件描述了系统应如何在每个运行级别中设置,并设置默认运行级别。 运行级别是进程的配置。 所有类 UNIX 系统都可以在不同的进程配置中运行,例如单用户模式,称为运行级别 1 或运行级别 S(或 s)。 在此模式下,只有系统管理员可以连接到系统。 它用于执行维护任务,而不会有损坏系统或用户数据的风险。 自然地,在这种配置中,我们不需要提供用户服务,因此它们都将被禁用。 另一个运行级别是重启运行级别,或运行级别 6,它根据适当的程序关闭所有正在运行的服务,然后重启系统。

使用 who 检查您当前的运行级别是什么

willy@ubuntu:~$ who -r
	run-level 2 2006-10-17 23:22		last=S

有关运行级别的更多信息,请参见下一节,请参阅第 4.2.5 节

在确定系统的默认运行级别后,init 通过在相应的rc目录中查找该运行级别来启动系统运行所需的所有后台进程。 init 运行每个 kill 脚本(其文件名以 K 开头)并带有 stop 参数。 然后,它在相应的运行级别目录中运行所有启动脚本(其文件名以 S 开头),以便正确启动所有服务和应用程序。 事实上,在系统完成启动后,您可以使用类似 /etc/init.d/httpd stopservice httpd stop 的命令以 root 身份登录手动执行这些相同的脚本,在本例中是停止 Web 服务器。

Note特殊情况
 

请注意,在系统启动时,通常会执行rc2.drc3.d中的脚本。 在这种情况下,没有服务被停止(至少不是永久停止)。 只有服务被启动。

实际上启动和停止服务的所有脚本都不位于/etc/rc<x>.d中。 相反,/etc/rc<x>.d中的所有文件都是指向位于/etc/init.d中的实际脚本的符号链接。 符号链接只不过是一个指向另一个文件的文件,在这种情况下使用它是因为它可以在不影响实际 kill 或启动服务的脚本的情况下创建和删除。 指向各种脚本的符号链接按特定顺序编号,以便它们按该顺序启动。 如果您希望在某个特定服务之前或之后立即启动或停止某个服务,则可以通过更改引用实际控制该服务的脚本的符号链接的名称来更改服务启动或 kill 的顺序,如下例所示,列出了/etc/rc5.d的内容,其中 crondxfs 都是从以 “S90” 开头的链接名启动的。 在这种情况下,脚本按字母顺序启动。

[jean@blub /etc/rc5.d] ls
K15httpd@     K45named@    S08ipchains@  S25netfs@      S85gpm@
K16rarpd@     K46radvd@    S08iptables@  S26apmd@       S90crond@
K20nfs@       K61ldap@     S09isdn@      S28autofs@     S90xfs@
K20rstatd@    K65identd@   S10network@   S30nscd@       S95anacron@
K20rusersd@   K74ntpd@     S12syslog@    S55sshd@       S95atd@
K20rwalld@    K74ypserv@   S13portmap@   S56rawdevices@ S97rhnsd@
K20rwhod@     K74ypxfrd@   S14nfslock@   S56xinetd@     S99local@
K25squid@     K89bcm5820@  S17keytable@  S60lpd@
K34yppasswdd@  S05kudzu@    S20random@    S80sendmail@

init 完成运行级别以达到默认运行级别后,/etc/inittab脚本为每个虚拟控制台(文本模式下的登录提示符)fork 一个 getty 进程。 getty 打开 tty 行,设置其模式,打印登录提示符,获取用户名,然后为该用户启动登录过程。 这允许用户验证自己的系统身份并使用它。 默认情况下,大多数系统提供 6 个虚拟控制台,但是您可以从inittab文件中看到,这是可配置的。

/etc/inittab还可以告诉 init 它应如何处理用户在控制台上按下 Ctrl+Alt+Delete 的情况。 由于系统应正确关闭并重新启动,而不是立即断电,因此告知 init 在用户按下这些键时执行命令 /sbin/shutdown -t3 -r now,例如。 此外,/etc/inittab声明了如果您的系统连接了 UPS 装置,init 在发生电源故障时应执行的操作。

在大多数基于 RPM 的系统上,图形登录屏幕在运行级别 5 中启动,其中/etc/inittab运行一个名为/etc/X11/prefdm的脚本。prefdm脚本根据/etc/sysconfig/desktop目录的内容运行首选的 X 显示管理器。 如果您运行 GNOME,这通常是 gdm,如果您运行 KDE,则通常是 kdm,但它们可以混合使用,并且还有一个随标准 X 安装一起提供的 xdm

但是还有其他可能性。 例如,在 Debian 上,每个显示管理器都有一个 init 脚本,并且/etc/X11/default-display-manager的内容用于确定要启动哪个显示管理器。 有关图形界面的更多信息,请参阅第 7.3 节。 最终,您的系统文档将解释有关 init 更高层方面的详细信息。

/etc/default和/或/etc/sysconfig目录包含一系列功能和服务的条目,这些条目都在启动时读取。 包含系统默认值的目录位置可能因您的 Linux 发行版而略有不同。

除了图形用户环境之外,还可以启动许多其他服务。 但是,如果一切顺利,您应该在启动过程完成后看到登录提示符或登录屏幕。

Note其他程序
 

我们解释了 SysV init 在基于 x86 的机器上的工作原理。 启动程序在其他架构和发行版上可能会有所不同。 其他系统可能使用 BSD 样式的 init,其中启动文件未拆分为多个/etc/rc<LEVEL>.d目录。 您的系统也可能使用/etc/rc.d/init.d而不是/etc/init.d.

4.2.5. Init 运行级别

在不同运行级别操作不同服务背后的想法本质上围绕着这样一个事实,即不同的系统可以以不同的方式使用。 有些服务只有在系统处于特定状态或模式(例如准备好供多个用户使用或具有可用的网络连接)后才能使用。

有时您可能希望在较低模式下操作系统。 例如,在运行级别 1 中修复磁盘损坏问题,这样其他用户就不可能在系统上,或者将服务器留在没有 X 会话运行的运行级别 3 中。 在这些情况下,运行依赖于更高系统模式才能运行的服务是没有意义的,因为无论如何它们都无法正常工作。 通过预先将每个服务分配为在其特定运行级别到达时启动,您可以确保有序的启动过程,并且您可以快速更改机器的模式,而无需担心手动启动或停止哪些服务。

可用运行级别通常在/etc/inittab中描述,下面部分显示了

#
# inittab   This file describes how the INIT process should set up
#           the system in a certain run-level.

# Default run level. The run levels are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS 
#	(The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:5:initdefault:
<--cut-->

随意配置未使用的运行级别(通常是运行级别 4),只要您认为合适。 许多用户以对他们来说最有意义的方式配置这些运行级别,同时保持标准运行级别保持默认状态。 这使他们能够快速进出其自定义配置,而不会干扰标准运行级别的正常功能集。

如果您的机器由于错误的/etc/inittab而无法启动,或者由于您已损坏的/etc/passwd文件(或者如果您只是忘记了密码)而无法让您登录,请启动到单用户模式。

Tip没有图形界面?
 

当您在文本模式下工作时,因为您的机器控制台上没有显示图形登录屏幕,您通常可以切换到控制台 7 或更高版本以获得图形登录。 如果不是这种情况,请使用命令 who -r 检查当前运行级别。 如果它设置为与/etc/inittab中的原始默认值不同的值,则系统很可能默认情况下不会在图形模式下启动。 在这种情况下,请联系您的系统管理员或阅读 man init。 请注意,切换运行级别最好使用 telinit 命令完成; 从文本控制台切换到图形控制台或反之亦然不涉及运行级别切换。

本指南中关于运行级别、脚本和配置的讨论力求尽可能通用。 存在许多变体。 例如,Gentoo Linux 将脚本存储在/etc/run levels中。 其他系统可能会首先遍历(较低的)运行级别并在到达最终运行级别并执行这些脚本之前执行其中的所有脚本。 请参阅您的系统文档以获取更多信息。 您还可以通读在/etc/inittab中引用的脚本,以更好地理解您的系统上发生了什么。

4.2.5.1. 工具

当您的系统上安装了 chkconfigupdate-rc.d 实用程序时,它们提供了一个简单的命令行工具,用于维护/etc/init.d目录层次结构。 这些实用程序使系统管理员无需直接操作/etc/rc[x].d.

下的目录中的大量符号链接。 此外,某些系统提供 ntsysv 工具,该工具提供基于文本的界面; 您可能会发现它比 chkconfig 的命令行界面更易于使用。 在 SuSE Linux 上,您会找到 yastinsserv 工具。 对于 Mandrake 的简易配置,您可能想要尝试 DrakConf,它允许在运行级别 3 和 5 之间切换等功能。 在 Mandriva 中,这变成了 Mandriva Linux 控制中心

大多数发行版都为配置进程提供了图形用户界面,请查看您的系统文档。

所有这些实用程序都必须以 root 身份运行。 系统管理员还可以手动在每个运行级别目录中创建适当的链接,以便在特定运行级别启动或停止服务。

4.2.6. 关机

UNIX 不是为了关机而设计的,但如果您确实必须关机,请使用 shutdown 命令。 完成关机程序后,-h选项将停止系统,而-r将重启系统。

如果系统在运行级别 1-5 中运行,则 reboothalt 命令现在能够调用 shutdown,从而确保系统正确关机,但这是一种不好的习惯,因为并非所有 UNIX/Linux 版本都具有此功能。

如果您的计算机无法自行断电,则在看到指示系统已停止或完成关机的消息之前,您不应关闭计算机,以便给系统时间卸载所有分区。 不耐烦可能会导致数据丢失。