Linux启动时间优化-initramfs裁剪

前言:

Linux系统启动时使用initramfs(intram file system)在启动初期提供一个用户态环境,用来完成一些内核在启动阶段不容易做或者不必要做的事情,如加载模块,定制化启动过程,执行/init进程等;initramfs制作时通常使用gzip或xz将数据压缩,再通过cpio进行归档。


裁剪过程

前面说过,initramfs通常进行压缩后归档,而启动的时候解压的步骤由内核完成,因此原始initrootfs的大小决定了解压的速度,当然,xz在实现了高压缩比的情况下解压速度是比较慢的,我们讨论的前提是同一压缩方式,本次我们使用的是gzip。未优化前解压initramfs的日志如下:

[    0.598371] Trying to unpack rootfs image as initramfs...
[    1.706403] Freeing initrd memory: 76116K

可以看到解压花费了1.1s左右的时间,initramfs大小为76116k。
系统启动后,可以在/boot目录查看initrd,具体的内容可以通过lsinitrd命令查看:

Image: initramfs.x86_64.img: 75M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x   3 root     root            0 Jan  1  1970 .
-rw-r--r--   1 root     root            2 Jan  1  1970 early_cpio
drwxr-xr-x   3 root     root            0 Jan  1  1970 kernel
drwxr-xr-x   3 root     root            0 Jan  1  1970 kernel/x86
drwxr-xr-x   2 root     root            0 Jan  1  1970 kernel/x86/microcode
-rw-r--r--   1 root     root        30546 Jan  1  1970 kernel/x86/microcode/AuthenticAMD.bin
-rw-r--r--   1 root     root      4898816 Jan  1  1970 kernel/x86/microcode/GenuineIntel.bin
========================================================================
Version: dracut-055-4.oe2203

可以使用initrd --unpack对initrd进行解压,解压之后查找大文件:

# du -sh *
4.0K    tmp
172M    usr
8.0K    var
...
# du -sh usr/lib/* | sort
0       usr/lib/os-release
16K     usr/lib/tmpfiles.d
20M     usr/lib/modules
220K    usr/lib/dracut
232K    usr/lib/udev
24K     usr/lib/ostree
28K     usr/lib/net-lib.sh
28K     usr/lib/sysctl.d
32K     usr/lib/dracut-lib.sh
4.0K    usr/lib/cifs-lib.sh
4.0K    usr/lib/dracut-dev-lib.sh
4.0K    usr/lib/initrd-release
44K     usr/lib/ignition
4.6M    usr/lib/kbd
53M     usr/lib/firmware
...

发现firmware占用了大量的空间,我们知道firmware是某些driver加载的时候需要传递给device的数据,而启动的时候仅需要加载少数驱动,大多数的驱动可以在启动之后从磁盘进行加载,因此firmware是可以去掉的;
使用lsinitrd -m可以查看initrd中内置了哪些dracut模块:

# lsinitrd -m initramfs.x86_64.img
Image: initramfs.x86_64.img: 75M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x   3 root     root            0 Jan  1  1970 .
-rw-r--r--   1 root     root            2 Jan  1  1970 early_cpio
drwxr-xr-x   3 root     root            0 Jan  1  1970 kernel
drwxr-xr-x   3 root     root            0 Jan  1  1970 kernel/x86
drwxr-xr-x   2 root     root            0 Jan  1  1970 kernel/x86/microcode
-rw-r--r--   1 root     root        30546 Jan  1  1970 kernel/x86/microcode/AuthenticAMD.bin
-rw-r--r--   1 root     root      4898816 Jan  1  1970 kernel/x86/microcode/GenuineIntel.bin
========================================================================
Version: dracut-055-4.oe2203

dracut modules:
systemd
scsi-rules
systemd-initrd
modsign
i18n
afterburn
ignition
network-legacy
network
ifcfg
url-lib
ignition-conf-fcos
rdcore
btrfs
btrfs
crypt
dm
kernel-modules
kernel-modules-extra
kernel-network-modules
mdraid
multipath
nvdimm
qemu
qemu-net
cifs
lunmask
resume
rootfs-block
terminfo
udev-rules
walinuxagent
dracut-systemd
usrmount
base
emergency-timeout
fs-lib
journal-conf
shutdown

可以选择性的将一些module去掉,这里我们去掉了llvm,issci,nfs等,dracut追加–omit="llvm iscsi nfs"参数;
dracut可以使用–strip参数,去掉制作文件的debug信息;还可以使用–hostonly选项,生成一个最小化的initramfs,使用此选项生成的initrd对硬件兼容性稍差。
经过一顿折腾,最终生成的initramfs大小为34M,内核启动时解压信息如下:

[    0.262957] Trying to unpack rootfs image as initramfs...
[    0.633050] Freeing initrd memory: 34368K

解压时间从1.1s减少到0.4s。

你可能感兴趣的:(linux,性能优化)