Linux下通过kexec快速重启时如何将USB系统img挂载为根分区
你之前操作启动失败的核心原因是仅加载了内核,未配套加载对应内核的initramfs(initrd),也没有指定根分区启动参数,内核找不到根文件系统自然无法启动完整OS。以下是两种可直接落地的实现方案:
前置准备
先提前处理USB上的OS镜像:
- 优先选择把镜像解包后,直接刷入USB设备的一个独立分区(比如
/dev/sda2,格式为ext4/xfs等Linux原生文件系统),省去loop挂载步骤,兼容性最高 - 若要保留img文件格式,确保img是包含完整根文件系统结构的raw镜像,内部有完整的
/sbin/init、/etc/fstab等必要系统文件 - 提前通过
lsblk命令确认USB设备在当前系统的设备路径,比如USB的第一个分区一般是/dev/sda1
方案1:kexec加载阶段指定根分区(优先选择,内核启动自动挂载)
直接在kexec命令中指定initrd和根分区参数,内核启动时自动完成根挂载,无需人工介入:
- 如果你已经把根文件系统刷入USB的独立分区(示例为
/dev/sda2,格式ext4),执行以下命令:
sudo kexec -l new_kernel.img \ --initrd=new_initrd.img \ --append="root=/dev/sda2 rootfstype=ext4 rw $(cat /proc/cmdline | sed 's/root=[^ ]*//')"
- 如果你要直接使用USB存储的img文件作为根分区(示例USB分区为
/dev/sda1,img路径为/usbos/rootfs.img,格式ext4),执行以下命令:
sudo kexec -l new_kernel.img \ --initrd=new_initrd.img \ --append="root=/dev/sda1 rootfstype=vfat rw loop=/usbos/rootfs.img loopfstype=ext4 $(cat /proc/cmdline | sed 's/root=[^ ]*//')"
命令执行完成后运行sudo kexec -e即可正常启动完整系统。
注意:需要提前把USB驱动、loop模块、对应文件系统驱动打包进new_initrd.img,否则会出现设备识别失败导致根挂载错误。
方案2:内核启动后手动切换根(兼容性更高)
如果方案1因initrd驱动缺失无法运行,可选择启动到临时shell后手动切换根:
- 执行带临时init参数的kexec命令:
sudo kexec -l new_kernel.img \ --initrd=new_initrd.img \ --append="init=/bin/bash rw $(cat /proc/cmdline | sed 's/root=[^ ]*//')"
- 运行
sudo kexec -e,内核启动后会直接进入bash临时shell - 按以下步骤完成根切换:
# 加载必要内核模块 modprobe usb-storage modprobe loop modprobe ext4 # 替换为你使用的文件系统对应的模块名 # 等待USB设备识别 sleep 3 # 挂载USB分区 mount /dev/sda1 /mnt # 挂载根文件系统:如果用img文件执行以下命令 mount -o loop /mnt/usbos/rootfs.img /new_root # 挂载根文件系统:如果用USB独立分区执行以下命令 # mount /dev/sda2 /new_root # 挂载必要虚拟文件系统 mount --bind /proc /new_root/proc mount --bind /sys /new_root/sys mount --bind /dev /new_root/dev mount --bind /run /new_root/run # 切换根并启动系统 chroot /new_root /sbin/init
内容的提问来源于stack exchange,提问作者iOS
相关产品推荐
相关产品推荐

