在 Windows 中通过 VirtualBox 启动物理硬盘上的 Linux 操作系统

VirtualBox 支持将实际的物理硬盘虚拟化(rawdisk,VMDK 文件),然后通过 VirtualBox 中的虚拟机来加载。折腾了几天,终于在我的 Windows 7 + OpenSUSE 双系统机器中实现了在 Windows 7 里的虚拟机中加载物理硬盘上的 OpenSUSE 系统。

要做这样的虚拟机,首先得是安装了双系统(当然多个系统也没问题)。可以是多重引导的,也可以不是。我的双系统并没有使用多重引导,而是开机直接进入 Windows 7,因为多重引导会妨碍 Win 7 系统的休眠功能 —— 这是我经常使用的功能。我使用安装在 U 盘上的 Grub 来启动 OpenSUSE 系统

简单介绍一下我的硬盘分区:硬盘分了 5 个区,C 盘是主要分区,安装了 Windows 7;D 盘是 ntfs 文件系统,做为 Windows 系统的数据盘;后面 3 个区分别是 OpenSUSE Linux 的根分区(/)、交换分区(/swap)和用户数据区(/home)。

在 Linux 系统中,这几个区分别识别为 /dev/sda1、/dev/sda5、/dev/sda6、/dev/sda7、/dev/sda8。

警告:
因为使用的是实际的物理硬盘,操作不当会引起数据丢失,并且多半无法恢复!如果出了问题我可不负责啊。
切记!切记!

下面开始记录在 Windows 7 中的 VirtualBox 虚拟机中引导物理硬盘后三个分区中的 OpenSUSE 系统的实现方法,与大家分享。

1. 配置 Linux 使用 UUID 标记硬盘设备分区

默认情况下,OpenSUSE 使用设备 ID 来标记硬盘的分区。按照这种标记方法,在虚拟机中是无法启动该系统的。所以需要先在 Linux 系统里将标记方式改为 UUID

A. 查询分区 UUID

进入 Linux 系统,查看设备的 uuid 并作记录,等会儿在 Windows 中配置虚拟机的时候还要用到:

sudo /usr/sbin/blkid
root's password:
/dev/sda1: ... ... ...
/dev/sda2: ... ... ...
/dev/sda5: ... ... ...
/dev/sda6: LABEL="OpenSUSE" UUID="4d123456-12cd-12cd-12cd-12cd56gh1234" TYPE="ext4"
/dev/sda7: UUID="4d323456-12cd-12cd-12cd-12cd56gh1234" TYPE="swap"
/dev/sda8: UUID="4d553456-12cd-12cd-12cd-12cd56gh1234" TYPE="btrfs"

其中后三个就是我的 Linux 分区,而 sda6 就是 Linux 的根分区,启动引导就到这里。记下其 UUID(我直接复制保存到一个文本文件了,存到了 Windows 分区中,待用)。

B. 修改 /etc/fstab

编辑 /etc/fstab 文件,将其中使用设备 ID 标记的分区改为 UUID 标记。例如,

/dev/sda6 / ext4 defaults 0 1
... ... ...
/dev/sda1 /mnt/Win7 ntfs-3g defaults 0 0

改为,

UUID=4d12... / ext4 defaults 0 1
... ... ...
UUID=82D2... /mnt/Win7 ntfs-3g defaults,noauto,ro 0 0

本来举一行例子就行了,这里最下一行比较重要,所以也列出来。可以看到,最下一行的分区是 Windows 7 系统的,之前是通过 ntfs-3g 来自动加载,现在必须设置为不自动加载(noauto),以及加载为只读(ro)。因为我们就是在 Windows 7 系统中运行虚拟机的,如果又在虚拟机中加载 Windows 的分区,那就,死循环了,会出现很严重的问题。

如果 fstab 文件中没有这一项,说明没有配置自动加载 Windows 分区,那就不用管了。但是要注意,千万不要在虚拟机里的 Linux 中加载 Windows 分区,特别是系统分区

C. 修改 Linux 启动项

OpenSUSE 默认使用 Grub2 来引导,其配置文件中已经使用了 UUID 来标记分区,所以不需要修改。

但是如果自己修改为 Grub 引导了,可能需要自己在 grub 的启动配置文件 menu.lst 中修改。如果是这样,建议复制一份正常启动的启动项,然后修改。(相当于在 menu.lst 中增加一个 entry。)

修改很简单,只要在,

kernel /vmlinuz ... ... ...

一行后面增加 root 位置就行了,如,

kernel /vmlinuz-linux root=/dev/disk/by-uuid/4d12... resume=/dev/disk/by-uuid/4d32...

另外,如果上面这一行启动项里面有 resume = /dev/sda7 选项,说明使用的是默认的 swap 分区(我这里是 sda7,前面的查询结果列表中显示了)作为休眠/恢复位置,也需要相应的将其设备 ID 修改为其 UUID(即,将实际的 swap 分区的设备 ID 修改为对应的 UUID)。

如果像我那样使用 U 盘上的 Grub 启动 Linux,下面还要按照同样的方法修改 U 盘上的 Grub 里的 menu.lst 文件。这里没有说,是因为 VirtualBox 中的虚拟机没法用 U 盘引导,而只能另外制作一个 grub 引导光盘来从光驱引导。

2. 制作 Grub 引导光盘

当然也可以用现成的 SuperGrubDisk 来做引导光盘。

这里参考网上的帖子制作一个定制化的 Grub 启动光盘,专门给虚拟机启动。

在前述 Linux 系统中,创建一个目录,

mkdir -p iso/boot/grub

将一个重要的文件复制进该目录,

cp /usr/lib/grub/stage2_eltorito iso/boot/grub

然后将 menu.lst 也复制进去,

cp /boot/grub/menu.lst iso/boot/grub

并且修改 menu.lst,按照前面 2.C 的要求将 root=… 放进去。

如果没有这个文件,就自己创建一个,内容为:

# This is a sample menu.lst file. You should make some changes to it.
# The old install method of booting via the stage-files has been removed.
# Please install GRLDR boot strap code to MBR with the bootlace.com
# utility under DOS/Win9x or Linux.
color blue/green yellow/red white/magenta white/magenta
timeout 6
default /default

title OpenSUSE Default
root (hd0,5)
kernel /boot/vmlinuz root=/dev/disk/by-uuid/4d.........
initrd /boot/initrd
boot

这里已经将 root=…/by-uuid/4d… 放进去了。

准备就绪,使用下面的命令行来创建启动光盘,

mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso iso/

将生成的 grub.iso 复制到 Windows 分区备用。

3. 在 Windows 中创建虚拟磁盘 vmdk

切换到 Windows 7 中,使用命令行窗口,执行,

cd C:\Program Files\Oracle\VirtualBox\

切换到 VirtualBox 安装目录。执行,

VBoxManage internalcommands createrawvmdk -filename "FILENAME" -rawdisk "\\.\PhysicalDrive#"
  • 其中 FILENAME 指的是要生成的 vmdk 文件的文件名,带路径,例如,d:\vm\hd.vmdk
  • 最后的 # 表示物理驱动器的编号,如果只有一块硬盘,通常为 0
  • 这样就会在 D 盘 vm 目录下创建一个 hd.vmdk 的文件,就是整块硬盘的虚拟磁盘了,大小打开只有 1kB。

当然,最保险的做法是仅仅虚拟化硬盘中的 Linux 分区,免得不小心在虚拟机中加载了 Windows 分区。这样就要求知道 Linux 分区是哪几个。可以这样来查看所有分区:

C:\Program Files\Oracle\VirtualBox>VBoxManage internalcommands listpartitions -rawdisk "\\.\PhysicalDrive0"
Number Type StartCHS EndCHS Size (MiB) Start (Sect)
1 0x07 0 /1 /1 1023/254/63 51207 63
5 0x07 1023/254/63 1023/254/63 186881 104872384
6 0x83 1023/254/63 1023/254/63 15000 487608320
7 0x82 1023/254/63 1023/254/63 2152 518330368
8 0x83 1023/254/63 1023/254/63 49998 522739712

可以看到,Linux 分区是这里的 6、7、8 三个。

那么,如果按照我这里的例子,创建只包含 6、7、8 三个分区的虚拟磁盘 linux_hd.vmdk 文件的方法就是:

VBoxManage internalcommands createrawvmdk -filename "D:\vm\linux_hd.vmdk" -rawdisk "\\.\PhysicalDrive0" -partitions 6,7,8

4. 在 Windows 中创建虚拟机并使用上面的虚拟磁盘

假设已经在 Windows 中安装 VirtualBox 这一步已经做过了。下面就打开 VirtualBox,新建一个虚拟机,在虚拟磁盘设置那一步,选择使用已有磁盘,然后选择刚才创建的虚拟磁盘 linux_hd.vmdk 即可。

剩下的就简单了。如果直接启动不行,那就使用我们创建的 grub.iso 做为启动介质来启动。

5. 删除该虚拟机

如果不想要这个虚拟机了,可以在 VirtualBox 中放心的删除它,删除时选择同时删除相关文件仅仅会删除我们创建的虚拟磁盘,并不会影响物理硬盘上的 OpenSUSE 分区。

嗯,其实我最初的目的是要在 OpenSUSE 中通过 VirtualBox 虚拟化运行 Windows 7 系统的。但是折腾了多天,Win 7 系统就是无法启动,总是在“Windows 正在加载文件”之后就重起了。如果有谁知道怎么回事,麻烦知会一声。

当然,这样的方法也可以用于其它 Linux 发行版,只不过我没有实际操作,就不多啰嗦了。©

本文发表于水景一页。永久链接:<http://cnzhx.net/blog/boot-linux-partition-on-physical-hd-with-vm-in-windows/>。转载请保留此信息及相应链接。

4 条关于 “在 Windows 中通过 VirtualBox 启动物理硬盘上的 Linux 操作系统” 的评论

  1. 以前折腾过虚拟机里启动硬盘里的xp,各种折腾不成功~~

  2. Mac上的Parallels能很容易的将BootCamp中的Windows虚拟化,福音啊!

    • 那感情好啊,最希望的就是将 Windows 给虚拟化了。如果最终也搞不定的话,就打算直接安装一个虚拟的 Windows 来日常使用了。

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)