[译]简述现代Linux系统如何启动

  • 2018-06-21
  • 262
  • 0

点此阅读原文

因为很多超出本文范围的原因,今天,我想要写一下现在Linux系统如何启动的概述。因为作为一个系统管理员总是卡在这里,我将会特别的关注失败的地方。

  1. 系统通过 BIOS MBR 启动 或 UEFI 以某种方式加载和启动 bootloader。这中间包含了非常多的步骤和可能出现的错误,比如:在安全引导系统未注册的UEFI bootloader,一般来说这种错误是最多的;系统报告没有东西可以引导,或者反复重启,或者bootloader中断引导,并给出一个迷之错误。

    在 UEFI系统上,bootloader需要在FAT32文件系统的EFI系统分区。有些人幸运的用正确的超级块格式制作了一个软RAID镜像;详见评论。

  2. bootloader加载自己的配置文件,需要另外的模块,通常在 /boot,也有可能在 UEFI系统分区中。这里失败的话会产生一个迷之错误,并把你带到 GRUB Shell中,或者会有一个理想的错误是 “can't find your menu file”。配置文件的位置通常是硬编码,有时候,你的分发版会选择一个不好的地方。

    对于GRUB,这个点必须在GRUB可以理解的文件系统和存储栈上,也就是Linux 内核可以理解的地方,幸运的是,现在,GRUB可以读懂很多文件系统,所以正常情况下,不大可能出现这种错误

    (某些GRUB设置必须是两阶段配置文件,第一阶段只加载第一个。这样就允许你更灵活的将第二个配置文件,放到其他地方,一般来说第二个更重要。)

  3. 通过配置文件,bootloader加载配置好的内核和ramdisk到内存中,然后将控制权交给内核。内核和 initramfs镜像也需要放在bootloader能加载的地方,不同的是,GRUB的配置文件允许你将它们放在任何你可以找到的地方(也不一定像 grub.cfg一样要放在一起,但是在 非UEFI系统上,通常在 /boot中)。

    这里有两个地方可能出错;grub.cfg中有已经不存在的内核条目,或者GRUB无法找到或启动内核存放的文件系统。后者可能发生的情况是:比如,grub.cfg 配置了错误的文件系统UUID。这个错误可以在运行中修复以便成功引导。

  4. 内核启动,创建 PID 1,然后用它运行从 initramfs 运行 /init。这个进程和做的事情围绕一个基本目标:找到并挂载根文件系统,然后将控制权转交。它会尝试组建软RAID设备和其他存储设备,如 LVM,设置sysctl配置,等等。这里最可能失败的地方是 initramfs 无法找到或者挂载根文件系统,这时会让你进入一个非常简陋的 救援Shell 中。如果出现这种错误,可能需要从 USB的镜像中启动系统,因为镜像中会有更好的工具和环境(通常失败的原因模糊不清)。

    在很多传统系统中,initramfs /init 是它自己一个分离的东西,通常是一个shell脚本,不同于系统的真正初始化。在基于systemd的系统中, initramfs /init 实际上就是 systemd自己。包括之前的 引导initramfs也是在systemd的控制下。一般来说 一个现代 initramfs 是一个真实的根文件系统,在进程看来就是 /。而且他的内容(配置和程序)通常是从根文件系统拷贝而来。可以用 lsinitrd 或者 lsinitramfs 这两个命令来查看。

    更新:事实证明,在某些Linux分发版上 initramfs 初始化还用一个脚本,特别是 Debian和Ubuntu。initramfs初始化变为systemd可能只有 RedHat系列(Fedora和RHEL)。

    关于 initramfs /init 如何转去运行在系统的根文件系统上的真实系统的init守护进程,已经超越了本文的范畴。也许命令很简单(systemd 只运行了 systemctl switch-root),但其做的工作是很复杂的。

    (某种程度上来说, systemd 是 initramfs /init 的时候会比较方便,因为意味着你不需要做多学另一个系统来查看initramfs是如何工作的;你只需要查看initramfs中的 systemd units,查看一下systemd的日志。)

  5. 真正的初始化系统用来配置系统的基础设置,并把系统带到一个正常运行的状态上;一般来说,在单用户模式下,这就是所有的工作了。这些设置包括设置hostname、挂载根文件系统以便可以写入、应用sysctl配置(这次是从真正的根文件系统)、配置网络包括回环网卡IPv4和IPv6本地地址、udev接管硬件,还有,挂载所有的本地文件系统(包括激活的底层存储系统,如: 软RAID,LVM,如果在 initramfs 没有被激活的话)。最常见的失败是,一个或者以上的文件系统没有办法挂载,这会导致初始化失败,并且进入单用户救援模式。

    (在基于 systemd 的系统中,hostname 其实被设置了两次,一次在 initramfs中,一次在这里。)

  6. 当本地文件系统挂载好,其他核心的配置也都就位,初始化系统会继续引导进行剩下的操作。包括:网络,启动所有守护进程,最后在console或者图形界面(GDM/LightDM)启用登录。到这里,系统就成功启动了。

    这里的错误可能是守护进程没有启动,或者更严重的,系统没有找到需要的网络设备,所以无法连入网络。不管怎么样,只会有一些错误信息(有可能看不到)或者有些地方工作不正常,最后还是能有一个登陆提示。只有很少的现代系统会在这里中断退出,并进入救援模式。

    基于 systemd的系统,这个控制权从 initramfs systemd 转换到 根文件系统 systemd(接管PID 1),不过 systemd 会保持状态和引导过程的连续性,你也可以在 journalctl 看到整个过程。切换发生汇报日志是 “Starting Switch Root…”,然后是 “Switching root.”。

System V init,Upstart 和 systemd 在‘基础系统设置’步骤 和 接下来的 ‘完全引导’步骤上都有区别,但他们以不同的方式实现。Systemd 不会在两个步骤中划出明显的界限,你可以用相同的方式在任一阶段加入自己的步骤。System V 倾向于用一个单独的运行级别来实现 ‘单用户’步骤,级别S,表示系统正在向目标级别转变。Upstart类似于两者的混合;它有一个启动事件,用来在完全引导之前,触发做一些事情。

(这仅仅是一个大概。在PC机上引导Linux已经变成一个复杂的过程,要配置和调整很多相关的东西。)


作者和出处(reposkeeper) 授权分享 By CC BY-SA 4.0 Creative Commons License

关注微信公众号,获取新文章的推送!
qrcode

评论

还没有任何评论,你来说两句吧

发表评论

*

code