计算机发展到如今,变的越来越复杂,集成的设备也越来越多。对于希望进一步了解硬件和OS如何协作运行的IT人员来说,咋一看可能很困难。所以这篇博客详细分解下整个启动过程,再复杂的事物也是由简单的东西组合协作配合工作的,复杂中总会有些简单的内容更有利于我们抓住更本质的东西。

Linux启动过程可以分为多个阶段:

第1步:电源和SMPS

计算机的主要组件之一是SMPS(Switching Mode Power Supply)。该组件的主要目标是为主板和其他计算机组件提供精准电压。

SMPS负责检查电源的供电情况。如果电压过高/过低,计算机就无法工作。一旦为计算机开始供电,SMPS就会检查其为主板提供的电压水平。如果电压是准确的,SMPS将向主板定时器发送POWER GOOD信号。

主板收到从SMPS收到POWER GOOD信号后,这意味着功率水平良好,计算机可以启动。主板定时器将停止向CPU发送复位信号。

第2步:引导

要完成引导过程,CPU必须知道上哪里搜索指令,因此必须对某些环节进行编程。在基于X86的计算机中,此程序地址位置几乎总是不变的。地址位置为 FFFF:0000h

该地址位置是ROM的最后一个区域。它只包含一条指令。该指令是跳转到另一个存储器地址位置。这个跳转命令将告诉ROM中BIOS程序的位置。

这就是计算机将如何知道BIOS程序的位置。

第3步:BIOS在启动过程中的作用

当按下开始按钮时,计算机知道如何自我启动,因为指令被送到称为BIOS(Basic Input Output System)的程序。在启动过程中,BIOS最重要的用途是开机自检。它由BIOS进行的一系列测试,以验证计算机的不同硬件组件的是否正常运行。

在加载操作系统之前,开机自检是非常重要的事情。试想一下,如果有一个有故障的硬盘或有故障的内存,有时这些东西会导致数据丢失。自检的目的就是检查并确认以下硬件组件的功能的完整性。

主要检查项包括:

  • 定时器IC
  • DMA控制器
  • 中央处理器
  • Video ROM

以下设备也将包括在自检环节内。

  • 母板
  • 键盘
  • 打印机端口
  • 硬盘等

如果您正在进行热启动(这意味着您重置了正在运行的计算机,大多数时候重置按钮是CPU上电源按钮附近的小按钮),BIOS将不会执行完整的开机自检。但是,如果正在进行冷启动,这意味着现在已经应用了电源,它将执行完整的开机自检流程。

BIOS通过查看预定义内存位置中的标志来确定它是冷启动还是热启动。一旦开机自检完成,BIOS将通过beep codes(通过系统扬声器)通知发现的任何问题。不同数量的beep codes具有不同的含义。

CMOSBIOS经常会混淆。CMOSBIOS是计算机主板中两个完全不同的东西。CMOS是一种小型内存RAM芯片,存在于主板中。该RAM与计算机主RAM芯片(可更换的存储芯片)不同。

目前主RAM芯片工作在千兆字节范围。与主RAM芯片不同,CMOS RAM在计算机关闭时不会刷新内存。它在一块名为CMOS电池的电池的帮助下记住所有配置。

  • 移除CMOS电池将使CMOS忘记先前保存的所有配置。这就是您可以通过简单地移除CMOS电池来解锁受CMOS密码保护的计算机的原因。
  • 取下CMOS电池会使操作系统显示错误的时间。因为在CMOS设置中保持系统时间一致性。

因此,始终建议定期更换CMOS电池,以确保计算机正常运行。

通常人们说我们修改了BIOS设置。但它完全错了。他们修改的实际上是CMOS设置。CMOS设置是修改引导顺序等的地方。用户不能更改BIOS设置。它需要制造商提供的闪存程序。

那么让我们回到我们的启动过程。开机检查成功完成后,BIOS将查看CMOS设置以了解引导顺序是什么。引导顺序只是用户定义的顺序,它告诉在哪里查找操作系统。

顺序如下:

  • CD ROM
  • 硬盘
  • USB
  • 软盘

上面显示的顺序意味着BIOS将首先查看CD ROM以检查是否可以从那里加载操作系统,如果它没有在CD ROM中找到可引导的磁盘,它将从硬盘上查看是否存在可引导的操作系统。然后USB,然后软盘。

假设您的CD ROM驱动器中没有可引导CD,则BIOS将转为HARD磁盘。

第4步:MBR和GRUB

现在,由于CD ROM驱动器中没有任何可引导CD,BIOS将从引导顺序设置中查看第二个设备。第二个设备是您的硬盘。

BIOS被编程为查看硬盘上的永久位置以完成其任务。此位置称为引导扇区。这只不过是硬盘的第一个扇区。该区域有时称为MBR(主引导记录)。这是有我们的计算机操作系统的程序的位置。一旦BIOS找到有效的MBR,它就会将MBR的全部内容加载到RAM,然后通过MBR的内容进一步执行。

硬盘的第一个扇区只有512个字节。是的,它的面积太小,无法容纳整个引导加载程序。因此,大多数操作系统只在此处存储第一阶段引导加载程序。第一阶段引导加载程序仅使用总共512字节中的前440个字节,其余部分用于存储分区表信息。

接下来将执行MBR前440个字节中的grub第一阶段程序。

您可以借助以下命令在Linux中完整转储/备份MBR。

root@ubuntu-dev:~# dd if=/dev/sda of=mbr bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000134061 s, 3.8 MB/s

上述命令的作用是简单地将第一个扇区的512个字节的内容转储到名为mbr的文件中。上面命令中的bs代表块大小。而count意味着只转储第一个扇区(转储将从硬盘的开头开始,大小为512字节)

MBR包含grub的第一个阶段和分区表信息。您可以从我们的MBR备份文件中查看分区表信息,如下所示。

root@ubuntu-dev:~# file mbr.bin
mbr.bin: x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 19451904 sectors; partition 2: ID=0x5, starthead 254, startsector 19455998, 2093058 sectors, code offset 0x63

在我的系统上只有两个分区,这就是它显示分区1和分区2的原因.MBR包含以下要总结的内容。从上面的mbr转储文件中显示的分区表内容,MBR中的Grub阶段1将查找其上设置了活动标志的分区。请记住,MBR中只能有一个活动分区。如你看到上面的分区表输出,则有活动标志的是分区1。

整个MBR的格式:

  • GRUB第一阶段程序(stage 1)
  • 分区表信息(Partition table information)
  • 错误消息(Error Messages)
  • 幻数(Magic Number)

幻数(Magic Number)是2个字节的幻数。该幻数用作MBR的验证方法。这个2字节的幻数将包含类似于AA55的值。不同的幻数表示MBR损坏或MBR无效。

第1阶段引导加载程序的主要工作是加载第二阶段引导加载程序。第二阶段引导加载程序是GRUB Stage 2,它实际上完成了加载内核和其他initrd镜像文件的工作。GRUB(Grand Unified Boot Loader)是grub不同阶段的组合名称。

现在有一个意外,我将在接下来揭示给大家。grub没有第二阶段。而是有三个阶段。 我会解释一下这背后的原因。这三个阶段如下所述。

  • GRUB Stage 1
  • GRUB Stage 1.5
  • Grub Stage 2

现在这个阶段1.5来自哪里。硬盘扇区从0到最后一个扇区计数。如前所述,第一个扇区(扇区0)包含GRUB Stage 1.通常,分区将不会在扇区63之前开始。所以分区将从扇区号63开始。因此,我们有扇区形式1-63空闲。此空间用于存储GRUB Stage 1.5。MBR和分区开头之间的这个空闲空间称为MBR GAP。

现在你可能会想到GRUB中这个额外的阶段是干什么的呢? 如果你是linux粉丝,你可能已经配置了grub配置文件。如果你记得配置,它包含内核文件的位置和名称,它的分区。现在grub如何在没有文件系统驱动程序的情况下访问那些内核文件?

位于MBR GAP中的Grub Stage 1.5(第一个分区开始之前的扇区1到63)基本上包含用于读取文件系统的驱动程序。因此grub阶段1将grub阶段1.5加载到RAM,并将控制传递给它。

现在grub stage 1.5将加载文件系统驱动程序,一旦加载了文件系统驱动程序,它现在可以访问/boot/grub/grub.conf文件,其中包含有关内核路径和initrd路径等的其他详细信息。

现在,您将看到一个漂亮的终端用户界面(Terminal user interface),您可以在其中选择操作系统内核,然后按Enter键启动它。

第5步 加载内核镜像

与GRUB类似,内核也分阶段加载。Linux内核负责处理进程管理,内存管理,用户,进程间通信等。我必须说内核从未被用户使用过。内核的作用是为程序运行保持良好的环境。我们使用内核管理不同的程序。

内核是一个压缩的镜像文件。此压缩内核镜像的位置在grub 2配置文件中指定。它基本上是一个可执行的bzImage文件。

现在你需要有很多驱动程序和模块来访问底层硬件和其他东西。例如,如果您在/ partition上配置了RAID,你将没有任何程序帮助下如何使用它呢?或者考虑如何包含内核模块或如何删除内核模块。所有这些都需要不同的程序和代码。如果在内核中包含所有这些代码将使内核尺寸变得更大。

但是我们的内核镜像文件需要更小,这就是它压缩镜像文件的原因。所以大多数这些驱动程序和工具以及一个类似的根文件系统感觉都是由initrd给出的。initrd有时被称为初始根文件系统。在切换到真正的根文件系统之前,内核会使用它。initrd以类似于内核镜像文件的镜像形式提供。让我们看看这个initrd图像文件的内容是什么。您可以在/ boot目录中找到initrd镜像文件和内核镜像文件。

[root@localhost initrd]# mv initramfs-2.6.32-358.14.1.el6.x86_64.img initramfs-2.6.32-358.14.1.el6.x86_64.gz
[root@localhost initrd]# gunzip initramfs-2.6.32-358.14.1.el6.x86_64.gz
[root@localhost initrd]# cpio -id < initramfs-2.6.32-358.14.1.el6.x86_64
90587 blocks
[root@localhost initrd]# ls
bin                 initqueue                             mount        sysroot
cmdline             initqueue-finished                    pre-pivot    tmp
dev                 initqueue-settled                     pre-trigger  usr
dracut-004-303.el6  initqueue-timeout                     pre-udev     var
emergency           initramfs-2.6.32-358.14.1.el6.x86_64  proc
etc                 lib                                   sbin
init                lib64                                 sys

如果上面你看到的命令,我们首先解压缩initrd镜像文件,然后我们可以在cpio命令的帮助下查看该文件的内容。

现在您可以看到initrd镜像文件的内容。有些文件夹与我们的linux目录结构非常相似。如/、/etc 、 /lib, /sbin包含一些必要的命令。它是一个小的根文件系统,内核在加载真正的根文件系统之前作为临时根文件系统加载。

内核模块的加载和卸载是在insmod、rmmod的帮助下完成的。

现在,当内核加载到内存中时,执行从检查处理器系列和体系结构开始。内核执行许多特定于硬件的操作,它执行的第一个用户空间程序是/sbin/init。

由于这是内核执行的第一个程序,因此它的进程ID号为1. init的进程ID号1没有被故意保留,只因为它是内核执行的第一个进程。现在,只要内核执行init进程,它就会查看/etc/inittab配置文件中的默认运行级别。

linux中有不同的运行级别。

运行级别用法
0系统暂停/关机
1单用户模式
2没有网络的多用户模式
3完全多用户模式
4没用过
5GUI/X11
6重启

/etc/inittab 文件配置默认的运行级别,如下所示。

id:3:initdefault:

现在这意味着,我们将运行级别3作为默认运行级别。一旦这些内容确定后,就会由内核启动特定级别的程序。这就是您拥有以下目录的原因。

[root@localhost]# cd /etc/rc.d/
[root@localhost rc.d]# ll
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 init.d
-rwxr-xr-x. 1 root root  2617 Jul 24 08:53 rc
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc0.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc1.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc2.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc3.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc4.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc5.d
drwxr-xr-x. 2 root root  4096 Oct  8 00:50 rc6.d
-rwxr-xr-x. 1 root root   499 Aug 13 10:55 rc.local
-rwxr-xr-x. 1 root root 19216 Jul 24 08:53 rc.sysinit

文件夹rc0.d,rc1.d,rc2.d等包含将根据inittab配置文件中的默认运行级别执行的特定于运行级别的程序。

让我们看看这些运行级文件夹中的内容是什么。

[root@localhost rc3.d]# ls
K01numad       K80kdump               S13cpuspeed          S28autofs
K01smartd      K84wpa_supplicant      S13irqbalance        S50choose_repo
K02oddjobd     K86cgred               S13rpcbind           S50cloud-init-local
K10psacct      K87restorecond         S15mdmonitor         S50mcelogd

如果您看到这些运行级别特定文件夹中的文件,它们要么以S开头,要么以K开头。文件也是编号的。现在启动时S的文件将在启动过程中执行,而以K开头的文件将在关机过程中被终止。

S或K之后的数字是执行这些程序的顺序。

一旦内核启动了所需的运行级别目录中的所有程序。您将获得一个登录屏幕,以便在启动的系统中登录。希望这篇文章有用且易于理解。如果有人在本文中发现错误,请告知我们,以便我们对其进行更正。

译者补充

每个发行版构建的initrd内容格式是不一样的,需要根据对应发行版的管理工具来查看/解压对应内容,比如CentOS 7开始,你需要使用skipcpio来查看和解压initrd

cd /tmp/initramfs
/usr/lib/dracut/skipcpio initramfs-3.10.0-229.el7.x86_64.img | zcat | cpio -ivd

当然文中提到的是基于SysvInit的发行版, /sbin/init本身是个链接,链接到/init文件,该文件是个sh脚本文件, 其中/sbin/init文件有个比较关键的环节是将用户的根盘挂载后,从内存文件系统切换到用户文件系统

exec /sbin/switch_root -c "/dev/console" "${CHROOT}" \
    "${REAL_INIT}" "${INIT_OPTS}"

对于新版本的基于Systemd的发行版,上述过程已经全权交由Systemd来处理了,不再是以脚本文件的形态存在,取而代之是/init、/sbin/init都统统链接到/usr/lib/systemd/systemd二进制文件,不过基于此,可以定制很多基于内存的操作系统。其实我们平常使用的livecd以及可启动的linux iso文件一直在使用该技术,cd本身是只读的,从cd将内存镜像加载到内存之后就是一个完整的基于内存的Linux操作系统了。甚至基于PXE等等技术可以启动大量基于网络的内存操作系统,用于系统环境数据收集以及对设备进行远程操作等等。

参考链接

【腾讯云】境外1核2G服务器低至2折,半价续费券限量免费领取!
https://cloud.tencent.com/act/cps/redirect?redirect=1068&cps_key=e4b50f6c64a4480367f8a8d16fd07c5a&from=console

标签: grub, boot, smps, bios, cmos, mbr, inittab

添加新评论