关于鸟哥是如何解开 initramfs 的:)

1. 问题:

        鸟哥解析 CentOS 7.x 的initramfs 档案内容 文章内容时, 主要疑问是为什么使用的是512bytes去算 “initramfs 档案的前置字元容量 ”的大小。

# 1.先取得initramfs前面应该要去除的容量有多少才对!使用下列方式取得 
[root@study ~]# mkdir /dev/shm/initramfs 
[root@study ~]# cd /dev/shm/initramfs 
[root@study initramfs]# cpio -i -d --no-absolute- filenames \ 
> -I /boot/initramfs-3.10.0-229.el7.x86_64.img 
22 blocks 
#这个重点就是在前面的字元占了几个block容量,每个block容量为512bytes,
# 因此,前面的部份就总共占了: 22 * 512 = 11264 个bytes 的意思!
# 每一个initramfs 档案的前置字元容量都不相同,所以需要先找出来去除才行!

2. 概念:

        initrd,initramfs的出现:硬件类型增多,要直接存储上的Linux kernel,需要硬件驱动, 而这些驱动由存放在文件系统根目录下, linux通过 虚拟档案系统(Initial RAM Disk或Initial RAM Filesystem) , 把这些启动引导需要的文档驱动加载到RAM中, 通过RAM上的init(systemd)加载我们实际存储上的(init)systemd, 完成后续的正常开机流程。

 

3. 处理过程:

1.  解析方法:

     可以参考 上一篇文章

2. initramfs格式:

根据解析方法看cenos不同版本cenos6 , cenos7, initramfs格式也是不同。以cenos7 为例,使用skipcpio工具可以实现解析:

skipcpio.c 功能是跳过一个cpio文件和 \0 将结果输出到另外一个文件。

centos7 可以使用 dracut 这个工具包进行处理 :
which
/usr/sbin/dracut
vi dracut 发现是个脚本。

centos7 initramfs分为两部分:

1). microcode blob 部分

# The microcode blob is _before_ the initramfs blob, not after
1594 if ! (
1595 umask 077
1596 cd "$early_cpio_dir/d"
1597 find . -print0 | cpio -B --null $cpio_owner_root -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
1598 ); then
1599 dfatal "dracut: creation of $outfile failed"
1600 exit 1

2). 具体的核心的文件部分

先cpio+gzip格式 $compress是可以指定格式(gzip, bzip2, lzma, xz, lzo, lz4)的模式gzip

1606 if ! (
1607 umask 077
1608 cd "$initdir"
1609 find . -print0 | cpio -B --null $cpio_owner_root -H newc -o --quiet | \
1610 $compress >> "${DRACUT_TMPDIR}/initramfs.img";
1611 ); then
1612 dfatal "dracut: creation of $outfile failed"
1613 exit 1
1614 fi

文件的两段内容都使用cpio进行的打包处理, 鸟哥使用512字节和cpio参数有关
man cpio
`-B’ Set the I/O block size to 5120 bytes. Initially the block size is 512 bytes.

3. 操作验证:

修改了下dracut脚本中cpio 的参数调整下 cpio 中block size大小, 以 -C 参数为例:
`-C IO-SIZE, –io-size=IO-SIZE’
Set the I/O block size to IO-SIZE bytes.

1.  备份

cp  /usr/sbin/dracut  /usr/sbin/dracut.backup

cp initramfs-3.10.0-862.el7.x86_64.img initramfs-3.10.0-862.el7.x86_64.img.backup

(不同内核文件名不同)

 

2. 修改

1594 if ! (
1595 umask 077
1596 cd "$early_cpio_dir/d"
1597 find . -print0 | cpio -C 4096 --null $cpio_owner_root -H newc -o --quiet > "${DRACUT_TMPD IR}/initramfs.img"
1598 ); then
1599 dfatal "dracut: creation of $outfile failed"
1600 exit 1

.......

1609 find . -print0 | cpio -C 4096 --null $cpio_owner_root -H newc -o --quiet | \
1610 $compress >> "${DRACUT_TMPDIR}/initramfs.img";

3. 执行

1)生成镜像:

dracut -f
如果要看日志可以将配置文件/etc/dracut.conf以下两行的注释取消;
7 logfile=/var/log/dracut.log
8 fileloglvl=6

日志中会有详细处理步骤

          2)计算microcode blob部分大小

cpio -C 4096 -i -d --no-absolute-filenames -I /boot/initramfs-3.10.0-862.el7.x86_64.img
4 blocks

输出 4 blocks, 计算获得  4*4096=16384 bytes

          3) 跳过 microcode blob生成新文件

dd解析, gzip+ cpio 完成initramfs文件解压操作 。

dd if=/boot/initramfs-3.10.0-862.el7.x86_64.img of=initramfs.gz bs=16384 skip=1

         4)解压

gzip -d initramfs.gz

        5)解包

cpio -i -d -H newc --no-absolute-filenames < initramfs
88177 blocks

       6) 查看

[root@centosgpt initramfs]# ls
bin early_cpio init kernel lib64 root sbin sys tmp var
dev etc initramfs lib proc run shutdown sysroot usr

        作者文章中使用的block size是 cpio 程序的模式参数Initially the block size is 512 bytes, 本篇文章生成镜像依赖于工具dracut

Be First to Comment

发表回复