发表了Windows 7对VHD文件的内建支持从VHD文件启动计算机这两篇博客后,陆续收到不少技术爱好者的电子邮件询问这些功能的细节、技术实现和应用场景。在做了一些功课之后,我整理汇总了这篇文章,详细全面的讨论一下Windows 7中VHD文件支持。

下面的一些信息和测试步骤都是根据Windows 7  Build 6801和Beta 1的,这篇文章发表于2009年1月22日。如果您看到这篇文章的时间比较晚了,可能有些具体的细节会随着Windows 7的进一步开发而发生变化,敬请留意!欢迎大家转载这篇文章,但请保证文章的完整性,并注明出处,谢谢!

理解VHD格式

绝大多数人最初接触VHD格式的文件,是在使用Virtual PC或者Virtual Server时,VHD是以文件形式存在的虚拟机的磁盘。微软在2005年公开了VHD格式文件的全部细节,可以从微软的TechNet网站下载Virtual Hard Disk Image Format Specification。这说明了微软不仅仅要把VHD应用在虚拟机领域,更希望VHD能够成为一种新的磁盘格式和载体在业界得到更多的支持。

让我们抛开虚拟机,把目光集中在VHD文件本身。VHD是一块虚拟的硬盘,不同于传统硬盘的盘片、磁头和磁道,VHD硬盘的载体是文件系统上的一个VHD文件。如果大家仔细阅读VHD文件的技术标准,就会发现标准中定义了很多Cylinder、Heads和Sectors等硬盘特有的术语,来模拟针对硬盘的I/O操作。既然VHD是一块硬盘,那么就可以跟物理硬盘一样,进行分区、格式化、读写等操作。

我们这可以这样认为,VHD也是硬盘的一种,就像2.5寸、3.5寸、SCSI、SATA、IDE等不同规格的硬盘一样,VHD是在一个文件中的硬盘

Windows 7支持VHD的技术实现方式

在讨论具体的技术实现方式之前,我们首先需要理解操作系统对磁盘和文件的管理。操作系统有磁盘系统和文件系统两部分,分别处理对硬盘的I/O读写指令(磁盘系统),和管理硬盘之上的分区、数据和文件格式(文件系统)。VHD是存在于文件之上的磁盘,可想而知它的技术实现必须横跨磁盘系统和文件系统这两部分。如果您对操作系统中这一部分不是非常的了解,可以听一听微软网站上的Windows存储技术系列Webcast

简单的说,要把VHD文件当作硬盘一样读写,必须有相应的驱动程序。在Virtual PC和Virtual Server中,微软就是通过在虚拟机种加入VHD的驱动程序,使得虚拟机可以从VHD启动并进行后续的操作。

在Windows 7中,微软把VHD的驱动内置进了操作系统,也包括在了Windows 7的引导程序中。这也就是说,我们可在使用Windows 7的时候,直接访问VHD文件中的内容(把VHD的硬盘映射到一个盘符,后面会详细描述),也可以通过Windows 7的引导程序,启动位于VHD磁盘上的另一个操作系统。理解VHD驱动的工作细节,需要比较多的Windows底层知识,下图是一个比较简单和抽象的结构,可以发现,VHD的驱动是跟磁盘驱动和文件系统紧密结合的。

142356209.png

眼花缭乱的VHD应用

既然在Windows 7中可以对VHD直接读写,让我们来看看这个强大的功能到底能有多少过人之处。

首先,我们可以用命令行工具Diskpart创建VHD文件!(是的,命令行工具,你可能已经想到了自动化批处理和批量部署可以用到这个技术,没错,网管说:要硬盘,于是,大量的VHD就被创建出来了… )

   1:  diskpart
   2:  create vdisk file=c:\windows7.vhd maximum=25600 type=fixed
   3:  select vdisk file=c:\windows7.vhd
   4:  attach vdisk
   5:  create partition primary
   6:  assign letter=r
   7:  format quick label=vhd
   8:  exit

上面这段命令,创建了一个固定尺寸的VHD文件,并且进行了分区、分配盘符和格式化,一气呵成。Diskpart还能做很多事情,具体参数,请参考这个文档,如果你不喜欢命令行,那么Windows 7的磁盘管理工具,一样可以完成上述操作。现在我们看看VHD在Windows 7中直接访问的几种方法:




方法一:如右图,Foo.VHD文件中可以包含一个以上的磁盘分区,这些分区都可以映射到Windows操作系统中,可以为之分配盘符,也可以映射到一个NTFS的目录。
142453488.png




方法二:如右图,VHD的磁盘中可以包含VHD文件,这个VHD文件还可以被映射到操作系统中,目前版本的Windows支持2层嵌套VHD。(我实在想不出有什么实际的用处,据说这个功能可能会在正式版中被去掉,以免把用户搞糊涂) 
142531356.png




方法三:如果你还没有被上面的嵌套VHD搞糊涂的话,让我们继续看右图。还记得VHD文件的差异磁盘功能吧?Bar.VHD在嵌套的基础上,使用物理C盘上的BarParent.VHD做成了一个差异磁盘。 

其实这种方法还是挺实用的,不考虑嵌套,Foo.VHD可以使用BarParent.VHD做差异磁盘,如果这样的话,从Foo.VHD启动计算机,每次用完都通过批处理自动销毁,硬盘保护卡的市场,恐怕从此要消失了。。。 
142624917.png






方法四:如右图,我们可以把网络共享里面的VHD文件,映射到系统中来。这个功能,结合上面的那个差异磁盘,对,小硬盘学生机,都不用硬盘保护卡勒!
142654483.png

这些功能的确令人眼花缭乱,我们冷静一下,看看VHD有什么局限性和功能上的限制:

  • 最多可以同时映射的VHD文件数量是512个(似乎也够用了) 

  • VHD磁盘的父分区,不支持Volume Snapshot 

  • 映射的VHD磁盘,不能被配置为动态磁盘,也就是不能在VHD上建软RAID(知足吧,VHD实现已经很复杂了,软RAID就不要来添乱了) 

从VHD启动计算机

如果说你对在Windows 7中映射和使用VHD文件无动于衷,那么,我相信从VHD启动计算机一定会抓住你的眼球。

我之前提到了,在Windows 7中,微软把VHD的驱动内置进了操作系统,也包括在了Windows 7的引导程序中。这也就是说,在启动计算机的阶段,Windows 7的引导程序可以大摇大摆的直接访问VHD文件,并且启动VHD中安装的系统。

慢着,什么是Windows 7的引导程序?简单地说,引导程序就是在操作系统内核或用户应用程序运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备(加载必要的驱动程序)、建立内存映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核或用户应用程序准备好正确的环境。我们在裸机上安装Windows 7时,首先做的,就是把Windows 7的引导程序写入磁盘的特殊位置。Windows 7的引导程序带有VHD驱动,因此可以从VHD启动。

要完成从VHD启动计算机,需要以下几个步骤:

你必须得让VHD中有一个操作系统先。有几种办法,可以用Virtual PC或者Virtual Server安装一个操作系统在VHD文件中,然后运行Sysprep,接着关闭虚拟机,这个VHD文件就可以用了。运行Sysprep是必须的,否则VHD下次启动时,仍旧加载虚拟机环境下的驱动程序,会导致蓝屏。

如果你想玩一个高级的,可以使用ImageX命令,把Vista的镜像,或者其它的磁盘镜像直接灌入VHD文件,下面是一个具体的演示。这些命令把Vista镜像灌入一个VHD,并且使用WinPE在物理机的磁盘上载入Windows 7的引导程序,用Windows 7引导程序启动硬盘上的VHD文件,注意:物理机本身没有安装Windows 7!

1. 用Diskpart创建VHD这里就不在赘述了,前面一段有这些命令。接着前面的一段命令,我们首先使用ImageX把一个操作系统的镜像,灌入VHD文件。WIM格式文件是Vista及以后版本Windows的安装镜像,在安装DVD中可以找到。

cd \d "c:\program files\<version>\tools\<architecture>\"
p_w_picpathx /apply <wim文件的路径> 1 r:\

2. WIM镜像被灌入VHD之后,使用Diskpart把VHD文件从当前的系统中卸载。

diskpart
select vdisk file=c:\windows7.vhd
detach vdisk
exit

3. 把这个准备好的VHD文件放到一个网络共享中备用。

net use y: \\network_share\
copy c:\windows7.vhd y:\network_share\vhd\

4. 使用Windows 7版本的WinPE光盘启动你的试验计算机,并运行如下命令把当前磁盘上的分区和数据清空。(注意,此操作会导致无法挽回的数据丢失,请一定要备份数据先)

diskpart
sel disk 0
clean

5. 接下来用Diskpart创建两个分区,分别是200M的S盘和默认剩余硬盘空间尺寸的C盘。S也成为系统分区,用于保存Windows 7的引导程序和相应必须的一些文件。然后把刚才放到网络共享的VHD文件,复制到C盘的根目录。

create partition primary size=200
format quick fs=ntfs
assign letter=s
active
create partition primary
format quick fs=ntfs
assign letter=c
exit

6. 用Diskpart命令加载VHD到当前的WinPE环境下,访问VHD中的Windows System32目录,并执行bcdboot命令完成启动所必需的初始化配置。bcdboot这个命令很神气,文档中的具体描述是:Use the BCDboot tool, located in the \System32 directory of the Windows 7 VHD, to copy the boot-environment files from the\Windows directory in the VHD to the system partition. The BCDboot tool will create the BCD configuration to boot from the VHD. For more information about the BCDboot tool, see BCDboot Command-Line Options in the OEM Preinstallation Kit (OPK) User's Guide or the Windows Automated Installation Kit (Windows AIK) User's Guide.

diskpart
select vdisk file=c:\windows7.vhd
attach vdisk
exit
cd v:\windows\system32
bcdboot v:\windows /s s:

7. 把WinPE光盘从光驱中移走,重启试验计算机,你会发现系统直接进入了VHD里面的Windows 7!

8. 如果你想在已有的Windows 7环境下配置配置一个从VHD的多启动选项,可以使用BCDEdit命令。(具体操作步骤在此)

142727721.png

上图是从VHD启动的大致结构,请注意VHD中操作系统的页面文件和Crashdump,不是包含在VHD中的,他们被保存在VHD文件的同一个目录中。

我们也需要了解一下VHD启动的一些注意事项和局限性:

1. 从VHD启动是有版本限制的,目前(2009年1月)的文档指出只有Windows Server 2008 R2、Windows 7商业版及以上版本,才支持此功能,未来正式发布时可能会有变化,敬请留意。

2. UDFS文件系统暂时不被支持(UDFS是什么?不支持也罢…)

3. 启动用的VHD文件,不能保存在压缩或者加密的NTFS磁盘之上(这一点很多人会忽略)

4. 根据一些朋友的反馈,动态的VHD文件无法启动,需要在建立vhd是设置成立即分配才可以从vhd启动

5. 如果你的物理硬盘是RAID格式,则必须要在VHD中的操作系统镜像中注入RAID的驱动程序,可以使用peimg命令。这个我没有测试过,感谢yueyezhan的反馈

性能性能性能

大家一定关心VHD的性能问题。相比物理磁盘,VHD的读写I/O性能指标对比如下,测试数据根据Windows 7 Build 6801获得,这些数据在近期的WinHEC大会上获得的。我们可以发现,相对于物理硬盘,VHD的读写开销非常小,只有在进行连续区块写入操作时,才跟物理硬盘有较明显的性能差异。

142809449.png

142902571.png

143014892.png

143127642.png

143145747.png

引用一些网友关于VHD的描述:

实验成功!
原系统是win7X86,灌装了一个X64的win7,在虚拟机里vhd上的X64win7成功启动
速度上感觉不出有差异
已经成功从VHD启动 
从磁盘管理可以看到当前系统盘C盘也就是20G的DISK2当然是VHD的啦,呵呵.
启动和运行速度和真机差不多吧~~
结论就是很好很强大,有着和真机几乎一样的速度,可以照完所有3D游戏,
说白了用起来和真机几乎没任何区别。Win7让多系统变得简单,
根本不用为分区烦恼,一个系统就一个vhd镜像,蹦了复制一份替换即可,
就像用虚拟机一样。当然虚拟的系统貌似只能是Win7及以上系统如server2008R2。
企业应用场景和未来展望

个人用户的多启动解决方案

企业操作系统的批量部署

接合差异磁盘的无盘(小盘)工作站,可以替代硬盘保护卡

 

就说这么多吧,还从来没有在LiveWeiter里面一下在写这么多内容呢,接下来大家多多做试验,集思广益吧!

http://blogs.technet.com/b/fyu/archive/2009/01/21/windows-7-virtual-hard-disk-vhd.aspx

 

 

从VHD文件启动计算机

/*以下内容根据Aviraj Ajgekar的博客文章编译和修改。*/

之前的文章提到了Windows 7对VHD文件的内建支持,从此以后VHD文件的地位得到了提升:-) 它可以被操作系统认为是一块物理的硬盘进行管理和读写。

我们知道,现在启动系统的方式多种多样,可以从光盘、硬盘、软盘、U盘、网络等等不同的渠道来完成。既然VHD可以被Windows 7认为是一块独立的物理硬盘,那么我们是否可以从VHD启动操作系统呢?

 

答案是肯定的。Windows 7的引导程序也同样包含了对VHD文件的读写驱动,因此在装有Windows 7引导程序(Boot Loader)的计算机上,可以通过配置BCDEdit的方式,把VHD上的操作系统加入到启动时显示的多系统选择菜单。

 

下面我们来看一下具体的步骤:

注意,我们不能在物理计算机上通过光盘把系统安装到VHD文件。首先我们需要一个已经安装了操作系统的VHD文件,这可以通过几种方式来完成:

1. 在Virtual PC或者Hyper-V中完成安装,并且运行sysprep,然后关机,这是的VHD文件可以被Windows 7的Boot Loader启动。

2. 使用ImageX工具,把之前备份的操作系统镜像文件(ImageX格式)恢复到VHD中。

这两种方法的具体步骤,在Aviraj Ajgekar的博客中有详细的描述。

 

Adding the VHD Entry in Boot Menu and then Boot from VHD

当成功的创建VHD文件并且在VHD系统之上部署了操作系统之后,我们需要使用Windows 7的BCDEdit工具来配置系统的多启动菜单:

C:\>bcdedit /copy {current} /d "My New VHD Description"

Note: This will Return the GUID of the Loader Object that you will use to replace <guid> below 
C:\>bcdedit /set <guid> device vhd=[driveletter:]\<directory>\<vhd filename> 
C:\>bcdedit /set <guid> osdevice vhd=[driverletter:]\<directory>\<vhd filename>

Note: vhd=[driveletter:]\<directory>\<vhd filename> is the new syntax supported for BCDEdit.exe to locate VHD File and Bootmgr will locate the partition containing the VHD File to boot from. 
C:\>bcdedit /set <guid> detecthal on

Note: 

Following is the attached screenshot of the my machine. In this case I have Windows 7 as the default OS and I have added the VHD File in the Boot Entry.

143548462.png

Well just after that run the following command to test if your boot entry is successfully created using C:\>bcdedit /v

143623820.png

Similarly, if you want to add multiple VHDs into Boot entry you can use the following lines to the command prompt

C:\>bcdedit /copy {current} /d "New VHD Description" 
C:\>bcdedit /set <guid> device vhd=[driveletter:]\<directory>\<vhd filename> 
C:\>bcdedit /set <guid> osdevice vhd=[driverletter:]\<directory>\<vhd filename> 
C:\>bcdedit /set <guid> detecthal on

Note:  detecthal is used to force windows to auto detect the Hardware Abstraction Layer.

If you want to delete any existing VHD entry from the Boot Menu you can always use the command C:\>bcdedit /delete <guid> /cleanup This deletes the specified operating system entry from the store and removes the entry from the display order.

Well, we are ready to Boot from VHD. Once you restart the computer you will see additional entry in Boot Menu along with the default Windows 7 or Windows Server 7 OS.

Here is the screenshot from newly booted Windows Server 2008 R2 Beta from VHD. I have installed Desktop Experience Pack and enabled Aero Glass.

143704783.png

看到这里,大家不免有一些问题:从VHD启动之后的系统,到底是运行在虚拟机上?还是直接运行在物理硬件之上?从VHD启动,还需要哪些必备的条件?是否会有性能的损失?下面我来回答这些问题:

 

1. Windows 7的引导程序和Windows 7本身都包含了对VHD文件的读写驱动程序,因此我们可以在启动计算机的时候,访问VHD并且从其上启动;我们也可以在Windows 7中直接创建、加载和卸载VHD文件。这些都是VHD读写驱动的功劳,跟Virtual PC或者Hyper-V没有直接的关系。因此Windows 7不需要安装任何虚拟化软件。

2. 从VHD启动之后,计算机的操作系统直接访问硬件,不是以虚拟化的方式运行。

3. 这里面唯一的区别,就是对文件系统读写访问的时候,需要经过额外的一层VHD读写驱动的解析,这里面有一些微量的I/O性能开销,但是跟虚拟化的情况相比,性能基本上接近了真机。我查了一些测试资料,有一组直接读取硬盘和读写VHD的比较,性能差别微乎其微。如下图:

143742983.png

4. 因为对VHD的支持仅包含在Windows 7中,因此我们不能在Windows 7中创建VHD后通过光盘给VHD安装任何操作系统。

 

这些仅仅是对这个功能的一些简单介绍和概括,相信大家在今后的应用中会有更多的体会和收获。

http://blogs.technet.com/b/fyu/archive/2009/01/19/vhd.aspx