initrd文件一般位于文件系统的/boot目录下,名称为initrd.img-<KERNEL_VERSION>.如:initrd.img-4.19.59-rt24
通过file查看文件格式为:
/boot/initrd.img-4.19.59-rt24: ASCII cpio archive (SVR4 with no CRC)

1. 解压initrd.img

unmkinitramfs /boot/initrd.img-4.19.59-rt24 initrdfs

解压的文件目录为:

initrdfs
├── early
├── early2
├── main

文件系统位于main下。

2. 修改文件系统

可直接在解压出的initrdfs文件夹里面修改。

1. 新增命令

新增的命令要看下命令依赖的库。需要将依赖的库一起复制到文件系统里面。
查看库依赖:

# ldd usr/bin/switch_root 
    linux-vdso.so.1 (0x00007fff063b6000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbccc2c9000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbccc517000)
  • linux-vdso.so.1: 该库由内核提供, 不需要复制。

2. 新增/删除内核模块

内核模块一般位于lib/modules/<KERNEL_VERSION>路径下。如: lib/modules/5.4.209-rt77-intel-pk-standard
新增/删除内核模块后需要更新模块列表。

depmod -b lib/modules/5.4.209-rt77-intel-pk-standard/ 5.4.209-rt77-intel-pk-standard
  • 5.4.209-rt77-intel-pk-standard: 内核版本号,需替换为实际的版本。

3. 挂载文件系统修改

将以下内容保存为文件chroot-mount.sh,使用该脚本进行挂载和卸载文件系统。挂载文件系统后,就可以使用文件系统内自带的命令,如apt等,也可以用于测试添加的命令是否正常运行。

#!/bin/bash

function mnt() {
        echo "MOUNTING"
        sudo mount -t proc /proc ${2}proc
        sudo mount -t sysfs /sys ${2}sys
        sudo mount -o bind /dev ${2}dev

        sudo chroot ${2}
}

function umnt() {
        echo "UNMOUNTING"
        sudo umount ${2}proc
        sudo umount ${2}sys
        sudo umount ${2}dev
}


if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
        mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
        umnt $1 $2
else
        echo ""
        echo "Either 1'st, 2'nd or both parameters were missing"
        echo ""
        echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
        echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
        echo ""
        echo "For example: ch-mount -m /media/sdcard/"
        echo ""
        echo 1st parameter : ${1}
        echo 2nd parameter : ${2}
fi

1. 挂载文件系统

chroot-mount.sh -m /root/initrdfs/main/
  • 文件系统后一定要加/

2. 卸载文件系统

chroot-mount.sh -u /root/initrdfs/main/

3. 重新制作initrd文件系统

制作initrd文件系统需要用到内核源码里面的命令:gen_init_cpiogen_initramfs_list.sh,位于内核源码的usr/目录下。

以下命令均在内核源码根目录下执行。
如果内核目录usr/下没有gen_init_cpio命令,可通过如下命令编译:

make -C usr/ gen_init_cpio

制作Initrd文件系统:

./usr/gen_initramfs_list.sh -o initrd.img -u 0 -g 0 /root/initrdfs/main
  • -o :输出文件名
  • -u :用户ID,root为0
  • -g :用户组ID,root为0

引用参考

Related Posts