less than 1 minute read

Linux的启动流程包括了:

  • 加载BIOS(Basic Input Output System)的硬件信息与进行自检(Power-On Self Test),并根据BIOS设置取得第一个可启动的设备
  • 读取并执行第一个启动设备内MBR(Master Boot Record)的启动引导程序(一般是grub2)
  • 根据启动引导程序的设置加载Kernel,Kernel会开始检测硬件与加载驱动程序
  • 在硬件驱动成功后,Kernel会主动调用systemd程序,并以default.target准备操作系统
    • systemd执行sysinit.target初始化系统及basic.target准备操作系统
    • systemd启动multi-user.target下的本机与服务器服务
    • systemd执行multi-user.target下的/etc/rc.d/rc.local文件
    • systemd执行multi-user.target下的getty.target及登录服务
    • systemd执行graphical需要的服务

当由boot loader读取内核文件后,Linux会将内核解压缩到内存当中,并且利用内核的功能,开始测试与驱动各个周边设备,包括存储设备、CPU、网卡、声卡等。此时Linux内核会以自己的功能重新检测一遍硬件,而不一定会使用BIOS检测到的硬件信息。内核文件一般会被放置到/boot里,取名为/boot/vmlinuz。

Linux内核是可以通过动态加载内核模块的(类似驱动程序),这些内核模块就放置在/lib/modules/目录内。由于模块放置到磁盘根目录内,因此在启动的过程中内核必须要挂载根目录,这样才能够读取内核模块提供的加载驱动程序功能。

虚拟文件系统(Initial RAM Disk或Initial RAM Filesystem)一般名为/boot/initrd或/boot/initramfs,这个文件的特色是它能够通过boot loader加载到内存中,然后这个文件会被解压缩并且在内存当中模拟成一个根目录,通过该程序来加载启动过程中所最需要的内核模块,通常这些模块就是USB、RAID等文件系统与磁盘接口的驱动程序。

systemd

内核加载完毕、进行完硬件检测与驱动程序加载后,内核会主动调用第一个程序,即systemd。systemd最主要的功能是准备软件执行的环境,包括系统的主机名、网络设置、语言设置、文件系统格式及其他服务的启动等。而所有的操作都会通过systemd的默认启动服务集合,即是/etc/systemd/system/default.target来规划。

default.target

CenOS 7的systemd启动流程是这样的:

  1. local-fs.target +swap.target:这两个target主要在挂载本机/etc/fstab里面所规范的文件系统与相关的内存交换分区。
  2. sysinit.target:这个target主要是检查硬件,加载所需要的内核模块等操作。
  3. basic.target:加载主要的外围硬件驱动程序与防火墙相关任务。
  4. multi-user.target:其他一般系统或网络服务的加载。
  5. 图形界面相关服务如gdm.service等其他服务的加载。

    sysinit.target

  6. 特殊文件系统设备的挂载:如dev-hugepages.mount、dev-mqueue.mount等挂载服务,主要在挂载跟内存分页使用与消息队列功能。
  7. 特殊文件系统的启用:包括磁盘阵列、网络驱动器、LVM文件系统、文件系统对照服务等
  8. 启动过程的信息传递与动画执行
  9. 日志式日志文件的使用:启用systemd-journald
  10. 加载额外的内核模块
  11. 加载额外的内核参数设置
  12. 启动系统的随机数生成器
  13. 启动动态设备管理器。

    basic.target

  14. 加载音效驱动程序
  15. 加载firewalld防火墙
  16. 加载CPU的微指令功能
  17. 启动与设置SELinux的安全上下文
  18. 将目前的启动过程所产生的启动信息写入到/var/log/dmesg当中
  19. 由/etc/sysconfig/modules/*.modules及/etc/rc.modules加载管理员指定的模块
  20. 加载systemd支持的timer功能

    multi-user.target

    一般服务的启动脚本设置都是放在下面的目录内:

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

兼容SystemV的rc-local.service
提供tty界面与登录的服务

graphical.target

如果default.target是Multi-user.target的话,这个步骤不会执行。反之会开始加载图形界面。

内核与内核模块

内核都具有可读取模块化驱动程序的功能。

  • 内核:/boot/vmlinuz或/boot/vmlinuz-version
  • 内核解压缩所需RAM Disk:/boot/initramfs(/boot/initramfs-version)
  • 内核模块:/lib/modules/version/kernel或/lib/modules/$(uname -r)/kernel

    boot loader:grub2

    grub2是目前Linux最主流的boot loader。 MBR是整个硬盘的第一个扇区中的一个区块,充其量整个大小也才446B。Linux将boot loader的程序代码执行与设置值加载分成了两个阶段。 grub2优点:

  • 识别与支持较多的文件系统,并且可以使用grub2的主程序直接在文件系统中查找内核文件
  • 启动时可以自行编辑与修改启动设置选项
  • 可以动态查找配置文件,而不需要在修改配置文件后重新安装grub2

    阶段一,执行boot loader主程序

    MRR或者启动扇区仅安装boot loader的最小主程序

    阶段二,主程序加载配置文件

    通过boot loader加载所有配置文件与相关的环境参数文件(包括文件系统定义与主要配置文件grub.cfg),一般来说这些配置文件都放在/boot下面。

    grub2配置文件维护

    grub2官方不建议手动修改grub2配置文件,而是通过/etc/default/grub环境配置文件与/etc/grub.d目录内的相关配置文件来处理。

    cat /etc/default/grub
    # 指定默认倒数读秒的秒数,不想等待输入0,一定让用户选择输入-1
    GRUB_TIMEOUT=5
    GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
    # 指定默认由哪一个选项来启动
    GRUB_DEFAULT=saved
    # 是否要隐藏此选项,通常是藏起来比较好
    GRUB_DISABLE_SUBMENU=true
    # 数据输出的终端格式,默认是通过命令行界面
    GRUB_TERMINAL_OUTPUT="console"
    # menuentry括号内的Linux16后接的内核参数
    GRUB_CMDLINE_LINUX="crashkernel=auto biosdevname=0 net.ifnames=0 rhgb quiet"
    # 取消恢复选项的制作
    GRUB_DISABLE_RECOVERY="true"
    

    配置完/etc/default/grub后执行grub2-mkconfig来重建grub.cfg

    initramfs

    内核模块放置于/lib/modules/$(uname -r)/kernel当中,这些模块必须要根目录(/)被挂载时才能够被读取。initramfs可以将/lib/modules/内的启动过程中需要的模块包成一个文件,然后在启动时通过主机的INT 13硬件中断功能将该文件读出来解压缩,并且initramfs在内存内会模拟成为根目录,因此我们的内核最后就能识别实际的磁盘,那就能进行实际根目录的挂载。所以initramfs内所包含的模块大多是与启动过程有关,而主要以文件系统及硬盘模块为主。

需要initramfs的时刻为:

  • 根目录所在磁盘为SATA、USB、SCSI等接口设备
  • 根目录所在文件系统为LVM、RAID等特殊格式
  • 根目录所在文件系统为非传统Linux支持的文件系统
  • 其他必须要在内核加载时提供的模块

Tags:

Categories:

Updated: