Debian的initrd.img文件

参考链接

  1. https://wiki.debian.org/Initrd

  2. https://blog.csdn.net/zhaominyong/article/details/119546892

initrd.img的作用

  1. 用于在启动时临时挂载根文件系统

  2. 加载关键驱动

  3. 切换到真正的根文件系统

initrd.img所处的位置

bash 复制代码
ls -lh /boot/initrd.img-*

可以看到有多个initrd.img文件

查看当前内核版本确定使用的initrd.img文件

bash 复制代码
uname -r

解压initrd.img

1. 查看压缩方式

bash 复制代码
file /boot/initrd.img-$(uname -r)
  • gzip compressed data → 压缩的CPIO归档

  • ASCII cpio archive → 未压缩的CPIO归档。

  • Linux rev 1.0 ext2 filesystem data → 旧式RAM磁盘映像

压缩方式为未压缩的cpio归档

2. 解压

bash 复制代码
cd /boot
sudo mkdir temp_initrd
cd temp_initrd
sudo cpio -idmv < /initrd.img-$(uname -r)

此时你会发现这并不是实际的initrd.img文件:(

因为Debian系统使用了另一套方式(initramfs-tools)来管理initrd.img文件

bash 复制代码
sudo unmkinitramfs /boot/initrd.img-$(uname -r) /boot/temp_initrd

使用这条命令才能正确地解压

之后打开文件夹,目录如下

bash 复制代码
/tmp/initrd/
├── main/      # 主 initramfs 内容(包含 init 脚本和核心文件)
│   ├── bin
│   ├── dev
│   ├── etc
│   ├── init    # 初始化脚本
│   ├── lib
│   └── ...
└── early/     # 早期加载的微码文件(如 CPU 微码更新)
    └── kernel/x86/microcode/AuthenticAMD.bin

查看initrd.img内部的执行命令

initrd.img内部执行操作由init脚本决定

使用cat命令打开init脚本后可以看到内部操作

bash 复制代码
cat /boot/temp_initrd/main/init
bash 复制代码
#!/bin/sh

# Default PATH differs between shells, and is not automatically exported
# by klibc dash.  Make it consistent.
export PATH=/sbin:/usr/sbin:/bin:/usr/bin

[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mkdir -p /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc

# shellcheck disable=SC2013
for x in $(cat /proc/cmdline); do
        case $x in
        initramfs.clear)
                clear
                ;;
        quiet)
                quiet=y
                ;;
        esac
done

if [ "$quiet" != "y" ]; then
        quiet=n
        echo "Loading, please wait..."
fi
export quiet

# Note that this only becomes /dev on the real filesystem if udev's scripts
# are used; which they will be, but it's worth pointing out
mount -t devtmpfs -o nosuid,mode=0755 udev /dev

# Prepare the /dev directory
[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd
[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin
[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout
[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr

mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true

# Export the dpkg architecture
export DPKG_ARCH=
. /conf/arch.conf

# Set modprobe env
export MODPROBE_OPTIONS="-qb"

# Export relevant variables
export ROOT=
export ROOTDELAY=
export ROOTFLAGS=
export ROOTFSTYPE=
export IP=
export DEVICE=
export BOOT=
export BOOTIF=
export UBIMTD=
export break=
export init=/sbin/init
export readonly=y
export rootmnt=/root
export debug=
export panic=
export blacklist=
export resume=
export resume_offset=
export noresume=
export drop_caps=
export fastboot=n
export forcefsck=n
export fsckfix=


# Bring in the main config
. /conf/initramfs.conf
for conf in conf/conf.d/*; do
        [ -f "${conf}" ] && . "${conf}"
done
. /scripts/functions

# Parse command line options
# shellcheck disable=SC2013
for x in $(cat /proc/cmdline); do
        case $x in
        init=*)
                init=${x#init=}
                ;;
        root=*)
                ROOT=${x#root=}
                if [ -z "${BOOT}" ] && [ "$ROOT" = "/dev/nfs" ]; then
                        BOOT=nfs
                fi
                ;;
        rootflags=*)
                ROOTFLAGS="-o ${x#rootflags=}"
                ;;
        rootfstype=*)
                ROOTFSTYPE="${x#rootfstype=}"
                ;;
        rootdelay=*)
                ROOTDELAY="${x#rootdelay=}"
                case ${ROOTDELAY} in
                *[![:digit:].]*)
                        ROOTDELAY=
                        ;;
                esac
                ;;
        nfsroot=*)
                # shellcheck disable=SC2034
                NFSROOT="${x#nfsroot=}"
                ;;
        initramfs.runsize=*)
                RUNSIZE="${x#initramfs.runsize=}"
                ;;
        ip=*)
                IP="${x#ip=}"
                ;;
        boot=*)
                BOOT=${x#boot=}
                ;;
        ubi.mtd=*)
                UBIMTD=${x#ubi.mtd=}
                ;;
        resume=*)
                RESUME="${x#resume=}"
                ;;
        resume_offset=*)
                resume_offset="${x#resume_offset=}"
                ;;
        noresume)
                noresume=y
                ;;
        drop_capabilities=*)
                drop_caps="-d ${x#drop_capabilities=}"
                ;;
        panic=*)
                panic="${x#panic=}"
                ;;
        ro)
                readonly=y
                ;;
        rw)
                readonly=n
                ;;
        debug)
                debug=y
                quiet=n
                if [ -n "${netconsole}" ]; then
                        log_output=/dev/kmsg
                else
                        log_output=/run/initramfs/initramfs.debug
                fi
                set -x
                ;;
        debug=*)
                debug=y
                quiet=n
                set -x
                ;;
        break=*)
                break=${x#break=}
                ;;
        break)
                break=premount
                ;;
        blacklist=*)
                blacklist=${x#blacklist=}
                ;;
        netconsole=*)
                netconsole=${x#netconsole=}
                [ "$debug" = "y" ] && log_output=/dev/kmsg
                ;;
        BOOTIF=*)
                BOOTIF=${x#BOOTIF=}
                ;;
        fastboot|fsck.mode=skip)
                fastboot=y
                ;;
        forcefsck|fsck.mode=force)
                forcefsck=y
                ;;
        fsckfix|fsck.repair=yes)
                fsckfix=y
                ;;
        fsck.repair=no)
                fsckfix=n
                ;;
        esac
done

# Default to BOOT=local if no boot script defined.
if [ -z "${BOOT}" ]; then
        BOOT=local
fi

if [ -n "${noresume}" ] || [ "$RESUME" = none ]; then
        noresume=y
else
        resume=${RESUME:-}
fi

mount -t tmpfs -o "nodev,noexec,nosuid,size=${RUNSIZE:-10%},mode=0755" tmpfs /run
mkdir -m 0700 /run/initramfs

if [ -n "$log_output" ]; then
        exec >"$log_output" 2>&1
        unset log_output
fi

maybe_break top

# Don't do log messages here to avoid confusing graphical boots
run_scripts /scripts/init-top

maybe_break modules
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
[ -n "${netconsole}" ] && /sbin/modprobe netconsole netconsole="${netconsole}"
load_modules
[ "$quiet" != "y" ] && log_end_msg

starttime="$(_uptime)"
starttime=$((starttime + 1)) # round up
export starttime

if [ "$ROOTDELAY" ]; then
        sleep "$ROOTDELAY"
fi

maybe_break premount
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount"
run_scripts /scripts/init-premount
[ "$quiet" != "y" ] && log_end_msg

maybe_break mount
log_begin_msg "Mounting root file system"
# Always load local and nfs (since these might be needed for /etc or
# /usr, irrespective of the boot script used to mount the rootfs).
. /scripts/local
. /scripts/nfs
. "/scripts/${BOOT}"
parse_numeric "${ROOT}"
maybe_break mountroot
mount_top
mount_premount
mountroot
log_end_msg

if read_fstab_entry /usr; then
        log_begin_msg "Mounting /usr file system"
        mountfs /usr
        log_end_msg
fi

# Mount cleanup
mount_bottom
nfs_bottom
local_bottom

maybe_break bottom
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom"
# We expect udev's init-bottom script to move /dev to ${rootmnt}/dev
run_scripts /scripts/init-bottom
[ "$quiet" != "y" ] && log_end_msg

# Move /run to the root
mount -n -o move /run ${rootmnt}/run

validate_init() {
        run-init -n "${rootmnt}" "${1}"
}

# Check init is really there
if ! validate_init "$init"; then
        echo "Target filesystem doesn't have requested ${init}."
        init=
        for inittest in /sbin/init /etc/init /bin/init /bin/sh; do
                if validate_init "${inittest}"; then
                        init="$inittest"
                        break
                fi
        done
fi

# No init on rootmount
if ! validate_init "${init}" ; then
        panic "No init found. Try passing init= bootarg."
fi

maybe_break init

# don't leak too much of env - some init(8) don't clear it
# (keep init, rootmnt, drop_caps)
unset debug
unset MODPROBE_OPTIONS
unset DPKG_ARCH
unset ROOTFLAGS
unset ROOTFSTYPE
unset ROOTDELAY
unset ROOT
unset IP
unset BOOT
unset BOOTIF
unset DEVICE
unset UBIMTD
unset blacklist
unset break
unset noresume
unset panic
unset quiet
unset readonly
unset resume
unset resume_offset
unset noresume
unset fastboot
unset forcefsck
unset fsckfix
unset starttime

# Move virtual filesystems over to the real filesystem
mount -n -o move /sys ${rootmnt}/sys
mount -n -o move /proc ${rootmnt}/proc

# Chain to real filesystem
# shellcheck disable=SC2086,SC2094
exec run-init ${drop_caps} "${rootmnt}" "${init}" "$@" <"${rootmnt}/dev/console" >"${rootmnt}/dev/console" 2>&1
echo "Something went badly wrong in the initramfs."
panic "Please file a bug on initramfs-tools."
相关推荐
kobe_OKOK_1 天前
windows 下载 pip包,debian离线安装
windows·debian·pip
ONE_SIX_MIX2 天前
Debian 的 网络管理器 被意外卸载,修复过程
服务器·网络·debian
迷路爸爸1802 天前
源码编译安装最新 tmux 教程(含 Debian/Ubuntu/CentOS/Arch/macOS 等系统)
linux·ubuntu·macos·centos·debian·tmux·archlinux
坐吃山猪2 天前
zk02-知识演进
运维·zookeeper·debian
木亦汐丫6 天前
Docker 镜像版本Alpine、Slim、Bookworm、Bullseye、Stretch、Jessie
运维·docker·容器·debian·alpine·slim·bullseye
天朝八阿哥10 天前
关于xfce4-pulseaudio-plugin中文翻译的bug
linux·debian
一文解千机12 天前
Termux Debian Arm64 源码编译安装坚果云,全平台同步笔记内容(也适用树莓派)
debian·termux·arm64·手机服务器·坚果云arm64·源码编译坚果云·termux坚果云
yy_xzz21 天前
Debian开发板TQ3658设置日期和时间显示 配置无法装入 发生未知的错误
运维·debian
1024find23 天前
Docker安装(Centos/Ubuntu/UOS)
ubuntu·docker·centos·debian
长不大的程序员25 天前
Linux系统-debian系的软件包管理
linux·运维·服务器·debian