Linux系统启动相关:vmlinux、vmlinuz、zImage,和initrd 、 initramfs,以及SystemV 和 SystemD

发布于:2025-05-17 ⋅ 阅读:(17) ⋅ 点赞:(0)

目录

一、vmlinux、vmlinuz、zImage、bzImage、uImage

二、initrd 和 initramfs

1、initrd(Initial RAM Disk)

2、initramfs(Initial RAM Filesystem)

3、initrd vs. initramfs 对比

4. 如何查看和生成 initramfs

三、SystemV 和 SystemD 的区别


一、vmlinux、vmlinuz、zImage、bzImage、uImage

vmlinux

是编译出来的最原始的内核文件,未经压缩的原始Linux内核可执行文件(ELF格式),包含调试符号,体积非常大。

主要用于内核调试(如用GDB分析崩溃),不直接用于启动系统。

vmlinuz

vmlinux的压缩版本(名称中的 z 表示压缩),去除了调试符号,体积更小,是bzImage/zImage文件的拷贝或指向bzImage/zImage的链接

实际用于系统启动的通用内核文件名称(如 /boot/vmlinuz-<version>

zImage

使用gzip压缩的小型内核镜像(适用于老式引导器),大小限制在约512KB

bzImage

Big zImage,同样压缩但支持更大内核(现代x86系统的标准格式)

大多数x86架构系统的标准启动文件(如 /boot/bzImage-<version>

uImage

uboot专用的内核镜像格式,在zImage/bzImage前添加U-Boot头(包含加载地址等信息)

嵌入式系统中使用U-Boot引导时必需的文件(如ARM开发板)


二、initrd 和 initramfs

initrd(Initial RAM Disk)和 initramfs(Initial RAM Filesystem)都是 Linux 内核在启动过程中使用的临时根文件系统,用于在挂载真正的根文件系统之前提供必要的驱动、工具和脚本。尽管它们的目的一致,但实现方式不同。以下是它们的区别、工作原理及使用场景:

1、initrd(Initial RAM Disk)

  • 基于块设备:initrd 是一个压缩的磁盘映像(通常是 gzip 压缩的 ext2 或 cramfs 文件系统),由引导加载器(如 GRUB)加载到内存。

  • 需要挂载:内核将其视为一个块设备(如 /dev/ram0),并挂载为临时根文件系统(/)。

  • 固定大小:需要预先分配固定大小的内存,可能导致资源浪费或空间不足。

工作流程

(1)引导加载器(如 GRUB)加载内核(vmlinuz)和 initrd 到内存。

(2)内核解压 initrd 并挂载为临时根文件系统(/)。

(3)initrd 中的 /linuxrc 或 /init 脚本执行,加载必要的模块(如磁盘驱动、LVM、加密等)。

(4)脚本挂载真正的根文件系统(如 /dev/sda1),并切换根目录(pivot_root 或 chroot)。

(5)真正的 init 进程(如 systemd 或 SysVinit)接管,initrd 被卸载。

由于其基于块设备,效率较低。且大小固定不够灵活,因此现代 Linux 系统已逐渐淘汰initrd,改用initramfs。

2、initramfs(Initial RAM Filesystem)

  • 基于 tmpfs(内存文件系统):initramfs是一个 cpio 归档文件(通常用 gzip 压缩),直接解压到内核的内存文件系统(tmpfs)。

  • 无需挂载:内核直接将其解压到根文件系统,无需额外的块设备驱动。

  • 动态大小:按需使用内存,更高效灵活。

  • 现代标准:从 Linux 2.6 开始成为默认机制。

工作流程

  1. 引导加载器 加载内核(vmlinuz)和 initramfs 到内存。

  2. 内核将 initramfs 解压到 tmpfs 并作为初始根文件系统(/)。

  3. /init(通常是 shell 脚本或 systemd)执行,加载必要的驱动和工具。

  4. 挂载真正的根文件系统,并切换根目录(pivot_root)。

  5. 真正的 init 进程接管,initramfs 被释放。

更快的启动速度(无需挂载块设备)。动态调整大小,节省内存。支持更复杂的早期用户空间(如 systemd 在 initramfs 中运行)。

3、initrd vs. initramfs 对比

特性 initrd initramfs
存储方式 块设备(如 /dev/ram0 tmpfs(内存文件系统)
格式 磁盘映像(ext2+gzip cpio 归档(gzip 压缩)
挂载方式 需要挂载为块设备 直接解压到内存
大小 固定大小 动态调整
性能 较慢(需块设备访问) 更快(直接内存访问)
现代使用 已淘汰(旧系统可能使用) 现代 Linux 默认机制

4. 如何查看和生成 initramfs

(1)查看 initramfs 内容

lsinitramfs /boot/initramfs-$(uname -r).img
# 或
unmkinitramfs /boot/initramfs-$(uname -r).img /tmp/initramfs

(2)生成initramfs

# Debian/Ubuntu(使用 update-initramfs)
update-initramfs -u -k $(uname -r)

# RHEL/CentOS(使用 dracut)
dracut --force /boot/initramfs-$(uname -r).img $(uname -r)

(3)手动创建 initramfs

# 1. 创建一个简单的 initramfs 目录结构
mkdir -p initramfs/{bin,dev,proc,sys}
# 2. 复制必要的工具(如 busybox)
cp /bin/busybox initramfs/bin/
# 3. 创建 init 脚本(必须是可执行的)
echo -e '#!/bin/sh\nmount -t proc proc /proc\nexec /bin/sh' > initramfs/init
chmod +x initramfs/init
# 4. 打包成 cpio.gz
(cd initramfs && find . | cpio -H newc -o | gzip > ../initramfs.cpio.gz)

三、SystemV 和 SystemD 的区别

SystemV 和 SystemD 是 Linux 系统中两种不同的初始化(init)系统,用于管理系统的启动和服务。

特性 SystemV (SysV) SystemD
启动方式 顺序执行脚本(串行) 并行启动服务
运行级别 0-6(如 runlevel3=多用户模式) 使用 target(如 multi-user.target
服务管理 /etc/init.d/ 脚本 + service/chkconfig systemctl + .service 单元文件
日志管理 依赖 syslog 内置 journalctl
依赖管理 手动定义启动顺序 自动依赖解析
默认配置文件 /etc/inittab /etc/systemd/system/default.target

根据Linux内核驱动流程,在架构有关的汇编代码完成特定初始化后,会调用start_kernel开始内核的初始化工作;

  • start_kernel函数中有关根文件系统挂载的简要执行流程概述如下:
start_kernel
  → vfs_caches_init()
    → mnt_init()
      → init_rootfs()          // 注册rootfs
      → init_mount_tree()      // 挂载rootfs到/
  → rest_init()
    → kernel_init()
      → do_basic_setup()
        → populate_rootfs()    // 处理initramfs/initrd
      → 检查/init是否存在?
        → 是:执行init_post()  // 用户空间接管
        → 否:prepare_namespace()
          → mount_root()       // 挂载真实根文件系统
          → sys_mount(".", "/", MS_MOVE) // 切换根目录
  • 其中,rest_init函数中依次创建了三个进程,idle进程,init进程以及kthreadd进程;
  • kernel_init函数中调用do_basic_setup函数,解压释放initramfs类型文件系统到rootfs的根目录,其中就必须包括/init可执行文件;

对于采用SystemV管理的系统

在系统启动过程中,/init可执行文件通常是init程序本身,在制作initramfs根文件系统时,需要将init程序打包进去,并确保/init指向这个init程序。init程序启动后,会读取/etc/inittab文件来确定系统的默认运行级别,并执行相应的脚本。
具体步骤如下:

  • 制作initramfs根文件系统时,将init程序打包进去。
  • 创建/init到init程序的软链接。
  • init程序启动后,读取/etc/inittab文件,确定系统的默认运行级别。
  • 根据运行级别,init程序会执行/etc/rc.d/rc script,该脚本会进一步调用/etc/rc.d/rc<number>脚本(其中<number>是运行级别)。
  • /etc/rc.d/rc<number>脚本会启动或停止相应的服务,以完成系统的初始化过程。

对于采用SystemD管理的系统,

  • 实际上/init可执行文件是systemd的符号链接,所以在init_post函数中执行的用户进程即为systemd;
  • 在制作initramfs根文件系统时,将systemd程序也打包进去,创建/init到systemd的软链接,即可启动systemd;
  • systemd启动后,完成后续的linux操作系统加载过程。

网站公告

今日签到

点亮在社区的每一天
去签到