Stay hungry,Stay foolish

0%

initramfs

TODO

细化执行流程

initramfs

initramfs - initial ram file system

initramfs是一个可以编译进内核的根文件映像,在Linux在启动init进程之前,用来准备系统,挂载真正的root文件系统,基于tmpfs

用cpio来归档,相对于tar:

  • cpio支持更广泛和更容易实现(代码层面)
  • cpio支持一些当时tar不支持的设备

通过gzip压缩

initramfs 长什么样

Ubuntu为例

1
2
3
4
root@dev:/tmp/test# ls -lh /boot/initrd.img-$(uname -r)
-rw-r--r-- 1 root root 36M Jun 12 2019 /boot/initrd.img-4.4.0-62-generic
root@dev:/tmp/test# file /boot/initrd.img-$(uname -r)
/boot/initrd.img-4.4.0-62-generic: gzip compressed data, last modified: Wed Jun 12 14:24:41 2019, from Unix

为了方便查看及测试,把/boot/initrd.img-$(uname -r)拷贝到/tmp/test/一份,同时添加.gz后缀

1
root@dev:/tmp/test# cp /boot/initrd.img-$(uname -r) initrd.img-$(uname -r).gz

gzip解压

1
root@dev:/tmp/test# gzip -d initrd.img-4.4.0-62-generic.gz

解压完毕后是一个cpio打包(归档)文件

1
2
root@dev:/tmp/test# file initrd.img-4.4.0-62-generic
initrd.img-4.4.0-62-generic: ASCII cpio archive (SVR4 with no CRC)

解包

1
cpio -idmv < initrd.img-4.4.0-62-generic

完全解开后的样子

1
2
root@dev:/tmp/test# ls
bin conf etc init initrd.img-4.4.0-62-generic lib lib64 run sbin scripts usr var

以可执行文件init为入口,分析initramfs都做了些什么

  1. 目录创建
  • /root
  • /dev
  • /sys
  • /proc
  • ...
  1. 挂载(伪代码)
  • mount -t sysfs /sys
  • mount -t proc /proc
  • mount -t tmpfs udev /dev
  • ...
  1. 一些块/字符设备创建
  • /dev/console
  • /dev/null
  1. 挂载/run并创建/run/initramfs目录

    1
    2
    mount -t tmpfs tmpfs /run
    mkdir -m 0755 /run/initramfs
  2. 读取/proc/cmdline并设定相关参数

  3. 驱动加载前的一些初始化操作

  4. 加载驱动(比如raid驱动,第三方存储设备驱动)

  5. mount 文件系统前的一些准备

  6. mount 当前的虚拟文件系统到真实的文件系统

    1
    2
    3
    4
    mount -n -o move /sys ${rootmnt}/sys
    mount -n -o move /proc ${rootmnt}/proc
    mount -n -o move /dev ${rootmnt}/dev
    mount -n -o move /run ${rootmnt}/run
  7. 切换/执行真实的文件系统中的init进程

    1
    exec run-init ${drop_caps} ${rootmnt} ${init} "$@" ${recovery:+--startup-event=recovery} <${rootmnt}/dev/console >${rootmnt}/dev/console 2>&

内核编译选型

  • CONFIG_BLK_DEV_INITRD=y
    开启(initramfs/initrd)支持

  • CONFIG_RD_GZIP=y
    支持GZIP,当然还有XZ BZIP2 LZMA 等

  • CONFIG_INITRAMFS_SOURCE="/usr/src/initramfs" 默认为空
    把指定位置的initramfs编译进内核映像文件(内核文件会变大). 当然initramfs也可以为独立文件,这时必须initrd=指定位置

initramfs可用来做什么

  • Mounting an encrypted, logical, or otherwise special root partition
  • Providing a minimalistic rescue shell (if something goes wrong)
  • Customize the boot process (e.g., print a welcome message)
  • Load modules necessary to boot (e.g., third party storage drivers)
  • Anything the kernel can't do that's usually handled in user space

    参考

  • Custom_Initramfs
  • initramfs