Linux基础学习笔记之——开机流程、模块管理与 Loader

开机流程、模块管理与 Loader

1、Linux 的开机流程分析

1.1、开机流程一览

系统开机的流程可概括如下:

  1. 加载 BIOS 的硬件信息与进行自我测试,并依据设定取得第一个可开机的设备;
  2. 读取并执行第一个开机设备内 MBR 的 boot Loader(即是 grub2,spfdisk 等程序);
  3. 依据 boot Loader 的设定加载 Kernel,Kernel 会开始侦测硬件与加载驱动程序;
  4. 在硬件驱动成功后,Kernel 会主动呼叫 systemd 程序,并以 default.target 流程开机;
    • systemd 执行 sysinit.target 初始化系统及 basic.target 准备操作系统;
    • systemd 执行 multi-user.target 下的本机与服务器服务;
    • systemd 执行 multi-user.target 下的 /etc/rc.d/rc.loacl 文件;
    • systemd 执行 multi-user.target 下的 getty.target 及登录服务;
    • systemd 执行 graphical 需要的服务。

1.2、BIOS、boot loader 与 kernel 载入

我们先对专用名词做个解释:

  • BIOS:不论是传统的 BIOS 还是 UEFI BIOS 都会被简称为 BIOS;
  • MBR:虽然分区表由传统的 MBR 以及新式的 GPT,不过 GPT 也有保留一部分兼容 MBR 的区块,因此,底下的说明在安装 boot loader 的部分,还是简称为 MBR。总之,MBR 就代表了该磁盘的最前面可安装 boot loader 的那个区块
1.2.1、BIOS、开机自我检测与 MBR/GPT

在个人计算机架构下,你想要启动整部系统首先就得要让系统去加载 BIOS,并通过 BIOS 去加载 CMOS 的信息,并且由 CMOS 内的设定值取得主机的各项硬件配置,例如 CPU 与接口设备的沟通频率、开机设备的搜寻顺序、硬盘大小与类型、系统时间等等。

在取得这些信息后,BIOS 还会进行开机自我测试(POST)。然后开始执行硬件侦测的初始化,并设定 PnP 设备,之后再定义出可开机的设备顺序,接下来就会开始进行开机设备的数据读取了

由于我们的系统软件大多放置在硬盘中!所以 BIOS 会指定开机的设备好让我们可以读取磁盘中的操作系统内核。但由于不同的操作系统它的文件系统格式不同,因此我们必须要以一个开机管理程序来处理内核文件加载问题,因此这个开机管理程序就被称为 Boot Loader。这个 Boot Loader 安装在哪呢?就是在开机设备的第一个扇区内,也就是我们一直说的 MBR(主引导分区)

既然内核文件需要 Loader 来读取,那每个操作系统的 Loader 都不相同,这样的话 BIOS 又是如何读取 MBR 内的 Loader 呢?其实 BIOS 是通过硬件的 INT 13 中断功能来读取 MBR 的,也就是说,只要 BIOS 能够侦测到你的磁盘(不论磁盘是 SATA 还是 SAS 接口),那他都有办法通过 INT 13 这条信道来读取该磁盘的第一个扇区内的 MBR 软件。

1.2.2、Boot Loader 的功能

刚刚说到 Loader 的最主要功能是要认识操作系统的文件格式并据此加载到内存中去执行。由于不同的操作系统的文件格式不一致,因此每种操作系统都有自己的 Boot Loader,用自己的 Boot Loader 才有办法加载自己的内核文件!那问题来了,你应该听说过多重系统吧?也就是一台主机上面安装多种不同的操作系统,既然1)必须使用自己的 Loader 才能加载属于自己的操作系统内核,而(2)MBR 只有一个,那你怎会有办法在一台主机上面同时安装多个系统呢

这就要回忆一下文件系统的功能了。其实每个文件系统都会保留一块启动扇区提供操作系统安装 Boot Loader而通常操作系统默认都会安装一份 Loader 到它的根目录所在的文件系统的 Boot Loader 上。如果我们的一台主机上安装 Windows 和 Linux 后,该 Boot Sector,Boot Loader 与 MBR 的相关性如下:

在这里插入图片描述

如上图所示,每个操作系统默认都会安装一套 Boot Loader 到它自己的文件系统中(就是每个 filesystem 左下角的方框),而在 Linux 系统安装时,你可以选择将 Boot Loader 安装到 MBR 中去,也可以选择不安装。如果选择安装到 MBR 的话,那理论上你在 MBR 和 Boot Sector 都会保持一份 Boot Loader 的程序。至于 Windows 安装时,它预设会主动的将 MBR 与 Boot Sector 都装上一份 Boot Loader所以你会发现安装多重操作系统时,你的 MBR 常常会被不同的操作系统的 Boot Loader 所覆盖

我们刚刚提到的问题还没解决!虽然各个操作系统都可以安装一份 Boot Loader 到它们的 Boot Sector 中,这样操作系统可以通过自己的 Boot Loader 来加载内核了问题是系统的 MBR 只有一个,你要怎么执行 Boot Loader 里面的 Loader 呢?这需要了解一下 Boot Loader 的主要功能

  • 提供菜单:用户可以选择不同的开机项目,这也是多重引导的重要功能!
  • 载入内核文件:直接指向可开机的程序区段来开始操作系统;
  • 转交其他 Loader:将开机管理功能转交给其他 Loader 管理。

由于具有选单功能,因此我们可以选择不同的内核来开机。而由于具有控制权转交功能,因此我们可以加载其他 Boot Sector 内的 Loader不过 Windows 的 Loader 预设不具有控制权转交功能,因此你不能使用 Windows 的 Loader 来加载 Linux 的 Loader

在这里插入图片描述

如上图所示,我的 MBR 使用 Linux 的 grub2 这个开机管理程序,并且里面假设已经有了三个选单,第一个选单可以直接指向 Linux 的内核文件并且直接加载内核来开机;第二个选单可以将开机管理控制权交给 Windows 来管理,此时 Windows 的 Loader 会接管开机流程,这个时候它就能够启动 Windows 了。第三个选单则是使用 Linux 在 Boot Loader 内的开机管理程序,此时会跳出另一个 grub2 的选单了:

  • 选单一:MBR(grub2)→ 内核文件 → booting
  • 选单二:MBR(grub2)→ Boot Sector(Windows Loader)→ Windows 内核 → booting
  • 选单三:MBR(grub2)→ Boot Sector(grub2)→ booting
1.2.3、加载内核侦测硬件与 initramfs 的功能

当我们由 Boot Loader 的管理而开始读取内核文件后,接下来,Linux 就会将内核文件压缩到内存中,并且利用内核的功能,开始测试与驱动各个周边的设备,包括存储设备、CPU、网卡、声卡等等。此时 Linux 内核会以自己的功能重新侦测一遍硬件,而不一定会使用 BIOS 侦测到的硬件信息。也就是说,内核正式接管了 BIOS 的工作。那么内核文件一般存放在哪呢?一般来说,它都会被放置到 /boot 里面,并且取名 /boot/vmlinuz 才对

[root@li ~]# ls  --format=single-column -F /boot
config-3.10.0-1127.el7.x86_64		#此版本内核被编译时选择的功能与模块配置文件
efi/		
grub/		#旧版的
grub2/		#就是开机管理程序 grub2 相关数据目录
initramfs-0-rescue-1b1f29b2be3d4dafbdcac2da7f5a3c15.img		#底下是虚拟文件系统文件!
initramfs-3.10.0-1127.el7.x86_64.img
symvers-3.10.0-1127.el7.x86_64.gz
System.map-3.10.0-1127.el7.x86_64
vmlinuz-0-rescue-1b1f29b2be3d4dafbdcac2da7f5a3c15*
vmlinuz-3.10.0-1127.el7.x86_64*		#内核文件。最重要的文件!

为了硬件开发商与其他内核功能开发者的便利,因此 Linux 内核是可以动态加载内核模块的这些内核模块通常放在 /lib/modules 目录内。由于模块放置到磁盘根目录内(要记得 /lib 不可以与 / 分别放在不同的分区!),因此在开机的过程中必须要挂在根目录,这样才能读取内核模块提供驱动程序的功能。而且为了担心影响到磁盘内的文件系统,因此开机过程中根目录是以只读的方式挂载的

虚拟文件系统一般使用文件名为 /boot/initrd 或 /boot/initramfs,这个文件的特色是,它能够通过 Boot Loader 加载到内存,然后这个文件会被加压缩并且在内存当中仿真成一个根目录,且此仿真在内存当中的文件系统能够提供一支可执行的程序,通过该程序来加载开机过程中所最需要的内核模块,通常这些模块就是 USB,RAID,LVM,SCSI 等文件系统与磁盘接口的驱动程序。等帮助内核重新呼叫 systemd 来开始后续的正常开机流程:

在这里插入图片描述

如上图所示,Boot Loader 可以加载 kernel 和 initramfs,然后在内存当中让 initramfs 解压缩称为根目录,kernel 就能够由此加载适当的驱动程序,最终释放虚拟文件系统,并挂载实际的根目录文件系统,就能够开始后续的正常开机流程。

在内核完整地加载完成后,你的主机应该就开始正确的运作了,接下来,就是要开始执行系统的第一支程序:systemd

1.3、第一支程序 systemd 及使用 default.target 进入开机程序分析

在内核加载完毕、进行完硬件侦测与驱动程序加载后,此时你的主机硬件应该已经准备就绪了,此时内核会主动呼叫第一支程序,那就是 systemd。这也是为啥使用 pstree -p 指令时,你会发现 systemd 的 PID 号码是 1 了systemd 最主要的功能是准备软件执行的环境,包括系统的主机名、网络设定、语系处理、文件系统格式以及其他服务的启动等而所有的动作都会通过 systemd 的默认启动服务集合,即 /etc/systemd/system/default.target 来规划。另外,systemd 已经舍弃了沿用多年的 runlevel 了。

1.3.1、常见的操作环境 target 与兼容与 runlevel 的等级

可以作为预设的操作环境的主要项目有:multi-user.target 以及 graphical.target 这两个。当然还有比较特殊的操作环境,包括 rescue.target,shutdown.target,emergency.target 等等,以及 initrd.target。

但是过去的 systemV 使用的一个称为 runlevel 的概念来启动系统的,systemd 为了兼容旧式的 systemV 操作行为,所以将 runlevel 与操作环境做个结合。

SystemVsystemd
init 0systemctl poweroff
init 1systemctl rescue
init [234]systemctl isolate multi-user.target
init 5systemctl isolate graphical.target
init 6systemctl reboot
1.3.2、systemd 的处理流程

当我们取得了 /etc/systemd/system/default.target 这一个预设操作界面之后,接下来系统会帮我们做什么呢?首先,它会链接到 /usr/lib/systemd/system/ 这个目录下去取得 multi-user.target 或 graphical.target 这两个其中的一个。假设我们使用的是 graphical.target ,接下来 systemd 会去找两个地方的设定,就是如下的目录:

  • /etc/systemd/system/graphical.target.wants/:使用者设定加载的 unit
  • /usr/lib/systemd/system/graphical.target.wants/:系统默认加载的 unit

然后由 /usr/lib/systemd/system/graphical.target 这个配置文件内发现如下内容:

[root@li ~]# cat /usr/lib/systemd/system/graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target		#必须先加载 multi-user.target 
Wants=display-manager.service	#启动完 graphical.target 之后,还必须启动 display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
[root@li ~]# cat /usr/lib/systemd/system/multi-user.target
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target		#必须先加载 basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

系统默认加载的 unit 有哪些?

[root@li ~]# ls /usr/lib/systemd/system/multi-user.target.wants/
dbus.service           plymouth-quit-wait.service      systemd-update-utmp-runlevel.service
getty.target           systemd-ask-password-wall.path  systemd-user-sessions.service
plymouth-quit.service  systemd-logind.service

使用者自定义的 unit 有哪些呢?

[root@li ~]# ls /etc/systemd/system/multi-user.target.wants/
auditd.service      kdump.service           rhel-configure.service  vmtoolsd.service
crond.service       NetworkManager.service  rsyslog.service
firewalld.service   postfix.service         sshd.service
irqbalance.service  remote-fs.target        tuned.service

其实,要知道系统的服务启动流程,最简单的方法就是 systemctl list-dependencies graphical.target 这个指令了。只是,如果你想知道背后的配置文件意义,那就要分别找出 /etc 与 /usr/lib 底下的 graphical.target.wants/ 目录下的数据就对了!当然,配置文件里面的 Requires这个值所代表的服务,也是需要先加载的。

1.3.3、systemd 启动 multi-user.target 下的服务

在加载了内核驱动硬件后,经过 sysinit.target 的初始化流程让系统可以存取后,加上 basic.target 让系统成为操作系统的基础,之后就是服务器要顺利地运行时,需要的各种主机服务以及提供服务器功能的网络服务的启动了。这些服务的启动则大多是附挂在 multi-user.target 这个操作环境下,你可以到 /etc/systemd/system/multi-user.target.wants/ 里面去看看预设的启动服务。也就是说,一般来说服务的启动脚本设定都是放在底下的目录的

  • /usr/lib/systemd/system:系统默认的服务启动脚本设定
  • /etc/systemd/syetem:管理员自己开发与设定的启动脚本

而用户针对主机的本地服务与服务器网络服务的各项 unit 若想要 enbale 的话,就是将它放到 /etc/systemd/system/multi-user.target.wants/ 这个目录底下做个链接,这样就可以在开机的时候自启了

[root@li lib]# systemctl enable vsftpd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/vsftpd.service to /usr/lib/systemd/system/vsftpd.service.
[root@li lib]# systemctl disable vsftpd.service
Removed symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service.
1.3.4、相容的 systemV 的 rc-local.service

过去用过 Linux 的用户大概都知道,当系统完成开机后,还想要让系统额外执行某些程序的话,可以将该程序指令或脚本的绝对路径名称写入到 /etc/rc.s/rc.local 这个文件中去。新的 systemd 机制中,它建议直接写一个 systemd 的启动脚本配置文件到 /etc/systemd/system 中去,然后使用 systemctl enable 的方式去设定启动它,而不要直接使用 rc.local 这个文件!

那新版的 systemd 有没有兼容的方法呢?当然有,那就是 rc-local.service 这个服务的功能。这个服务不需要启动,它会自己判断 /etc/rc.d/rc.local 是否具有可执行的权限来判断要不要启动这个服务。

#1、先看一下 /etc/rc.d/rc.local 的权限,然后检查一下 multi-user.target 有没有这个服务
[root@li lib]# ll /etc/rc.d/rc.local
-rw-r--r--. 1 root root 473 8月   7 01:30 /etc/rc.d/rc.local

[root@li lib]# systemctl status rc-local.service
● rc-local.service - /etc/rc.d/rc.local Compatibility
   Loaded: loaded (/usr/lib/systemd/system/rc-local.service; static; vendor preset: disabled)
   Active: inactive (dead)
[root@li lib]# systemctl list-dependencies multi-user.target | grep rc-local
#明明就有这个服务,但是 rc.local 不具有执行的权限,因此这个服务不会被执行

#2、加入 x 权限后,再看一下 rc-local 是否可被执行
[root@li lib]# chmod a+x /etc/rc.d/rc.local; ll /etc/rc.d/rc.local
-rwxr-xr-x. 1 root root 473 8月   7 01:30 /etc/rc.d/rc.local
[root@li lib]# systemctl daemon-reload
[root@li lib]# systemctl list-dependencies multi-user.target | grep rc-local
● ├─rc-local.service		#这个服务确实被记录到启动的环境下了

通过 chmod a+x /etc/rc.d/rc.local,你的许多脚本可以放在 /etc/rc.d/rc.local 这个文件内,系统在每次开机时都会去执行这文件内的指令。

1.3.5、开机过程会用到的主要配置文件

基本上,systemd 有自己的配置文件处理方式,不过为了兼容 systemV,其实很多的脚本设定还是会读取位于 /etc/sysconfig/ 底下的环境配置文件。常见的配置文件:

  • 关于模块:/etc/modprode.d/.conf 及 /etc/modules-load.d/.conf

    其实还有两个地方可以处理加载模块的问题:

    • /etc/modprode.d/*.conf:单纯要内核加载模块的位置;
    • /etc/modules-load.d/*.conf:可以加上模块参数的位置。
  • /etc/sysconfig/*

    • authconfig

      这个文件主要在规范使用者的身份认证的机制,包括是否使用本机的 /etc/passwd,/etc/shadow 等,以及 /etc/shadow 密码记录使用何种算法加密。

    • cpupower

      启动 cpupower.service 服务时,就会读取这个文件。

    • firewalld,iptables-config,etables-config

      与防火墙有关的参数

    • network-scripts/

件主要在规范使用者的身份认证的机制,包括是否使用本机的 /etc/passwd,/etc/shadow 等,以及 /etc/shadow 密码记录使用何种算法加密。

  • cpupower

    启动 cpupower.service 服务时,就会读取这个文件。

  • firewalld,iptables-config,etables-config

    与防火墙有关的参数

  • network-scripts/

    网卡设置参数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值