调整分区大小后更正 VirtualBox 原始磁盘 VMDK 文件
Correcting VirtualBox raw disk VMDK file after resizing a partition
我在第二个硬盘驱动器(Ubuntu 中的 /dev/sdb2)的第二个分区上安装了 Windows 8.1,使用命令
创建
VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
一切正常 - Windows 安装可以从 VirtualBox 运行,甚至 bootable 通常可以从 GRUB 运行。上次在Windows安装软件时(PC开机直接进入Windows),发现系统分区(/dev/sdb2)上space不够用,就把它放大了HDD 上剩余的 15 GB。
这些更改使得 Windows 安装当然无法在 VirtualBox 中使用 - 它无法启动并提供一些修复选项。我意识到需要做的第一件事是扩大 VMDK 文件中的分区,所以我备份了旧的 sdb2.vmdk 和 sdb2-pt.vmdk 文件,并使用与以前相同的命令重新创建它们。
然而,这并没有改变,因为 sdb2-pt.vmdk 似乎正在存储引导记录(在我的例子中是 MBR,目前使用 GRUB)和 Windows 需要的更多东西好好工作。我的下一次尝试是将新的 sdb2-pt.vmdk 替换为旧的(使用 Windows 引导程序和可能的旧分区 table)——这也没有用。
如何使用新的分区大小更新 VMDK 文件以再次从 VirtualBox 进行放大的 Windows 8.1 安装 bootable?
我终于自己找到了解决办法。由于 VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
命令根据 当前 磁盘结构生成两个有效文件,唯一需要的更改是从旧的 [=13] 恢复 Windows 引导加载程序=] 文件,这是一个相当简单的过程。如果您只想学习恢复步骤,可以跳过以下理论部分。
关于 VMDK 文件格式的一些背景信息
VMWare 磁盘格式 (VMDK) 由两个文件组成 - 描述符文件(原始问题中的 sdb2.vmdk
)和扩展文件(sdb2-pt.vmdk
)。它们的内部结构在 VMWare 的 specification 中有很好的定义。我将总结最重要的部分:
描述符文件 (sdb2.vmdk
) 包含一个带注释的部分 # Extent description
,它看起来像这样:
# Extent description
RW 63 FLAT "sdb2-pt.vmdk" 0
RW 41943040 ZERO
RW 83886080 FLAT "/dev/sdb" 58722304
RW 2 FLAT "sdb2-pt.vmdk" 63
RW 1191843568 ZERO
一个范围描述(来自上面的行)具有以下结构:
Access Size in sectors Type of extent Filename (Offset)
偏移量参数(仅为 FLAT
类型范围指定)指定给定范围在文件 Filename
中的偏移量(以扇区为单位)。请注意,文件 sdb2-pt.vmdk
包含两个范围,前 63 个扇区长,第二个只有 2 个扇区长。
FLAT
扩展文件 sdb2-pt.vmdk
是一个原始数据二进制文件,与您将获得的文件相同,例如在类 Unix 系统上使用 dd
命令。由于扇区大小在我的例子中是 512 bytes
(我不知道这是否是一般规则),sdb2-pt.vmdk
文件(基于上面范围描述中描述的新磁盘分区)是 (63+2)*512 bytes
长.
现在是第二个范围(只有 2 个扇区大小的范围)。这是在扩大 Windows 分区后在我的新分区 table 中出现的填充范围(描述 table 中的第三个范围)。由于我之前的分区 table 不包含任何此类填充,旧的 sdb2-pt.vmdk
文件仅包含前 63 个扇区长度,因此比 [=12= 生成的新分区小 1 024 字节] 命令。这显然导致旧扩展文件和新扩展文件不兼容。
恢复过程
请注意以下步骤仅适用于旧的 MBR 磁盘结构!
您肯定希望保留新的分区结构并将分区 table 中所做的任何更改传播到 VMDK 文件。继续以下步骤:
- 备份您的旧描述文件 (
sdb2.vmdk
) 和扩展文件 (sdb2-pt.vmdk
)。在接下来的步骤中,您将只需要第二个,但您永远不知道还会发生什么。
发出命令生成新的描述符和范围文件:
VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
现在,新描述文件 (sdb2.vmdk
) 中的第一个范围条目应该如下所示:
RW ## FLAT "sdb2-pt.vmdk" 0
知道你想保留新分区 table(以及后面的所有内容)并且只恢复存储在备份扩展文件中的 Windows 引导加载程序(旧 sdb2-pt.vmdk
),您必须将第一个 440 bytes
(引导加载程序)从旧扩展文件复制到新扩展文件。这可以使用十六进制编辑器(复制从地址 0x0 到 0x1B8 的所有值)或在类 Unix 系统上使用以下命令完成:
dd if=old-sdb2-pt.vmdk of=sdb2-pt.vmdk bs=1 count=440
中提琴.
在 github 上有一个工具可以自动执行此操作(并且重新运行 相同的选项将更新其 vmdk 和辅助文件,因此您可以稍后更改分区)https://github.com/vasi/vmdk-raw-parts
我在第二个硬盘驱动器(Ubuntu 中的 /dev/sdb2)的第二个分区上安装了 Windows 8.1,使用命令
创建VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
一切正常 - Windows 安装可以从 VirtualBox 运行,甚至 bootable 通常可以从 GRUB 运行。上次在Windows安装软件时(PC开机直接进入Windows),发现系统分区(/dev/sdb2)上space不够用,就把它放大了HDD 上剩余的 15 GB。
这些更改使得 Windows 安装当然无法在 VirtualBox 中使用 - 它无法启动并提供一些修复选项。我意识到需要做的第一件事是扩大 VMDK 文件中的分区,所以我备份了旧的 sdb2.vmdk 和 sdb2-pt.vmdk 文件,并使用与以前相同的命令重新创建它们。
然而,这并没有改变,因为 sdb2-pt.vmdk 似乎正在存储引导记录(在我的例子中是 MBR,目前使用 GRUB)和 Windows 需要的更多东西好好工作。我的下一次尝试是将新的 sdb2-pt.vmdk 替换为旧的(使用 Windows 引导程序和可能的旧分区 table)——这也没有用。
如何使用新的分区大小更新 VMDK 文件以再次从 VirtualBox 进行放大的 Windows 8.1 安装 bootable?
我终于自己找到了解决办法。由于 VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
命令根据 当前 磁盘结构生成两个有效文件,唯一需要的更改是从旧的 [=13] 恢复 Windows 引导加载程序=] 文件,这是一个相当简单的过程。如果您只想学习恢复步骤,可以跳过以下理论部分。
关于 VMDK 文件格式的一些背景信息
VMWare 磁盘格式 (VMDK) 由两个文件组成 - 描述符文件(原始问题中的 sdb2.vmdk
)和扩展文件(sdb2-pt.vmdk
)。它们的内部结构在 VMWare 的 specification 中有很好的定义。我将总结最重要的部分:
描述符文件 (sdb2.vmdk
) 包含一个带注释的部分 # Extent description
,它看起来像这样:
# Extent description
RW 63 FLAT "sdb2-pt.vmdk" 0
RW 41943040 ZERO
RW 83886080 FLAT "/dev/sdb" 58722304
RW 2 FLAT "sdb2-pt.vmdk" 63
RW 1191843568 ZERO
一个范围描述(来自上面的行)具有以下结构:
Access Size in sectors Type of extent Filename (Offset)
偏移量参数(仅为 FLAT
类型范围指定)指定给定范围在文件 Filename
中的偏移量(以扇区为单位)。请注意,文件 sdb2-pt.vmdk
包含两个范围,前 63 个扇区长,第二个只有 2 个扇区长。
FLAT
扩展文件 sdb2-pt.vmdk
是一个原始数据二进制文件,与您将获得的文件相同,例如在类 Unix 系统上使用 dd
命令。由于扇区大小在我的例子中是 512 bytes
(我不知道这是否是一般规则),sdb2-pt.vmdk
文件(基于上面范围描述中描述的新磁盘分区)是 (63+2)*512 bytes
长.
现在是第二个范围(只有 2 个扇区大小的范围)。这是在扩大 Windows 分区后在我的新分区 table 中出现的填充范围(描述 table 中的第三个范围)。由于我之前的分区 table 不包含任何此类填充,旧的 sdb2-pt.vmdk
文件仅包含前 63 个扇区长度,因此比 [=12= 生成的新分区小 1 024 字节] 命令。这显然导致旧扩展文件和新扩展文件不兼容。
恢复过程
请注意以下步骤仅适用于旧的 MBR 磁盘结构!
您肯定希望保留新的分区结构并将分区 table 中所做的任何更改传播到 VMDK 文件。继续以下步骤:
- 备份您的旧描述文件 (
sdb2.vmdk
) 和扩展文件 (sdb2-pt.vmdk
)。在接下来的步骤中,您将只需要第二个,但您永远不知道还会发生什么。 发出命令生成新的描述符和范围文件:
VBoxManage internalcommands createrawvmdk -filename sdb2.vmdk -rawdisk /dev/sdb -partitions 2
现在,新描述文件 (
sdb2.vmdk
) 中的第一个范围条目应该如下所示:RW ## FLAT "sdb2-pt.vmdk" 0
知道你想保留新分区 table(以及后面的所有内容)并且只恢复存储在备份扩展文件中的 Windows 引导加载程序(旧
sdb2-pt.vmdk
),您必须将第一个440 bytes
(引导加载程序)从旧扩展文件复制到新扩展文件。这可以使用十六进制编辑器(复制从地址 0x0 到 0x1B8 的所有值)或在类 Unix 系统上使用以下命令完成:dd if=old-sdb2-pt.vmdk of=sdb2-pt.vmdk bs=1 count=440
中提琴.
在 github 上有一个工具可以自动执行此操作(并且重新运行 相同的选项将更新其 vmdk 和辅助文件,因此您可以稍后更改分区)https://github.com/vasi/vmdk-raw-parts