侧边栏壁纸
博主头像
Matt's Blog

行动起来,活在当下

  • 累计撰写 12 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

虚拟机安装X86 ImmortalWrt系统扩容

Matt
2026-01-14 / 0 评论 / 0 点赞 / 34 阅读 / 0 字

ImmortalWrt作为一个嵌入式系统,其能适配的存储大小在镜像构建时已经确定,通常官方给出的镜像存储大小都只有几百M,即便虚拟机分配远大于此的空间,也是浪费,必须手动扩容以利用分配的空间:

安装后扩容

安装工具:

opkg update
opkg install parted
opkg install resize2fs

重建分区(输入fdisk /dev/sda后一步一步输入指令):

fdisk /dev/sda
d
2
n
2
First sector (起始扇区): 输入  原分区的起始点
Last sector (结束扇区):直接回车(默认使用所有剩余空间)。

reboot

如果遇见重启失败,卡在如图所示:

你在使用 fdisk 删除并重建分区 /dev/sda2 时,虽然数据保留了,但是该分区的 PARTUUID (分区唯一标识符) 发生了变化(被重新生成了)。 然而,GRUB 引导配置文件(grub.cfg)里仍然写着旧的 UUID(就是截图中 b83072dc... 那一串)。引导程序按着旧号码找分区,找不到,就卡在 Waiting for root device 了。

这是一个非常经典的问题。

原因分析: 你在使用 fdisk 删除并重建分区 /dev/sda2 时,虽然数据保留了,但是该分区的 PARTUUID (分区唯一标识符) 发生了变化(被重新生成了)。 然而,GRUB 引导配置文件(grub.cfg)里仍然写着旧的 UUID(就是截图中 b83072dc... 那一串)。引导程序按着旧号码找分区,找不到,就卡在 Waiting for root device 了。

解决方法: 你需要临时修改引导参数让系统启动,进去之后再修复配置文件。

方法一:启动时临时修改(最快)

  1. 强制重启虚拟机

  2. 进入 GRUB 菜单: 在虚拟机启动画面(BIOS/Logo 画面)刚过,马上疯狂按 Shift 键或 Esc 键,或者 方向键上下,目的是为了卡住 GRUB 引导菜单,不让它自动倒计时进入系统。

  3. 编辑模式: 当你看到 ImmortalWrt / OpenWrt 的启动选项列表时,选中第一项,按键盘上的 e 键进入编辑模式。

  4. 修改参数

    • 在屏幕上找到以 linux 开头的那一行代码。

    • 找到 root=PARTUUID=b83072dc-.... 这一段。

    • 删掉 PARTUUID=xxxx-xxxx... 这一长串。

    • 改成 root=/dev/sda2

    • (注意:保留行里其他的参数,比如 rootwait 等,只改 root= 后面这部分)。

  5. 启动: 按 F10Ctrl + x 按照现在的配置启动。

此时系统应该能成功启动并进入控制台。

进入系统后永久修复(关键)

通过“方法一”成功进入系统后,必须修改配置文件,否则下次重启又会挂。

  1. 挂载引导分区(如果未挂载):

    Bash

    mount /dev/sda1 /boot
    
  2. 查看新的 UUID(可选,确认用): 输入 blkid,你会看到 /dev/sda2 现在有了全新的 PARTUUID。

  3. 修改 grub.cfg: 你可以选择把配置改回 UUID 模式,或者直接用 /dev/sda2(虚拟机环境通常设备名固定,用设备名也没问题)。

    编辑配置文件:

    Bash

    vi /boot/grub/grub.cfg
    

    (如果没有 vi,尝试用 nano,或者直接用 sed 命令替换)

    简单粗暴修复法(推荐虚拟机使用): 直接把配置文件里所有的 root=PARTUUID=....... 替换为 root=/dev/sda2

    vi 中:

    • i 进入编辑模式。

    • 找到所有 PARTUUID=... 的地方,手动改成 /dev/sda2

    • Esc,输入 :wq 回车保存。

  4. 最后执行扩容(如果你之前没做完): 既然都进来了,别忘了执行最后一步扩容文件系统:

    Bash

    resize2fs /dev/sda2
    
  5. 重启验证

    Bash

    reboot
    

若发生如下错误:

resize2fs /dev/sda2

resize2fs 1.47.0 (5-Feb-2023)

Filesystem at /dev/sda2 is mounted on /; on-line resizing required

old_desc_blocks = 1, new_desc_blocks = 1

resize2fs: Invalid argument While checking for on-line resizing support

这是 OpenWrt/ImmortalWrt 在 x86 架构下的一个经典“怪癖”。

原因分析: 虽然你已经把分区(sda2)拉大了,但是因为 /dev/sda2 当前正作为根目录(/)被系统挂载使用中,内核处于“自我保护”状态,拒绝了对正在运行的根文件系统进行在线调整(On-line resizing),所以报错 Invalid argument

这里有两种解决办法,建议先试方法一,不需要重启,成功率很高。

方法一:使用 Loop 设备“欺骗”扩容(推荐)

既然不能直接对 /dev/sda2 操作,我们可以把它映射成一个虚拟的 Loop 设备,绕过内核对“根设备”的直接检查。

请依次执行以下命令:

  1. 将分区映射为 Loop 设备

    Bash

    losetup /dev/loop0 /dev/sda2
    

    如果提示 losetup: not found,请先运行 opkg install losetupopkg install mount-utils。不过一般系统自带。

  2. 对 Loop 设备执行扩容

    Bash

    resize2fs -f /dev/loop0
    

    注意:这里加了 -f (force) 参数,强制执行。

  3. 验证结果: 如果输出类似 The filesystem on /dev/loop0 is now XXXXX blocks long,说明成功了! 此时执行 df -h 查看 / 的空间应该已经变大了。

安装前扩容

还有一种更优的扩容方式,就是对img镜像进行扩容,这样不管wrt恢复设置或者再次安装,都可以直接使用扩容的大内存。

# 给img镜像末尾填充2GB空数据 (count=2000 表示增加 2GB 的空间)
dd if=/dev/zero bs=1M count=2000 >> immortalwrt.img



# 为了将2GB空间真正赋予具体的分区,使用分区工具parted操作镜像。
parted immortalwrt.img


# 查看分区情况
print
# 调整分区大小 (将第 2 个分区扩展至镜像文件的 100%)
resizepart 2 100%
# 查看是否扩展成功
print
# 退出分区工具
quit

#挂载镜像为块设备:
losetup -P /dev/loop0 immortalwrt-24.10.0.img

#刷新分区表(确保内核识别到了你刚才用 parted 改大的分区):
partprobe /dev/loop0

扩容文件系统(针对第 2 分区):
resize2fs /dev/loop0p2

#卸载设备:
losetup -d /dev/loop0

在UP主悟空的日常博客,中从parted执行完quit就完成了,但在实践中还必须完成其下面步骤,我是用的parted 版本为debian系统 3.5,可能是在较新的版本中,它只负责修改分区表(Partition Table)。它并不具备修改 ext4 文件系统内部元数据的功能。

0

评论区