[转]Hyper-V 虛擬化技術(Hyper-V 2.0)

源地址:http://www.dotblogs.com.tw/daniel07793/archive/2012/04/09/71362.aspx

======================================================

在談這東西之前,就一定要先聊聊,Hypervisor這東西

不論是VMWare vSphere,或是Hyper-V,都一定會有這東西

這是Guest OS存取Hardware必定經過的一層,另一個名稱叫做Virtual Machine Monitor

首先,先來看看有啟用Hyper-V跟沒有啟用Hyper-V的開機差異

enable_Hyper

(左圖是未啟用Hyper-V、右圖是啟用Hyper-V)

當Hypervisor被啟用之後,將會使用%Systemroot%\System32\Drivers底下的hvboot.sys先載入Hypervisor

hyper-v_boot

接著在透過實際的CPU來決定使用哪一種VT技術,%Systemroot%\System32底下的hvax64.exe或者hvix64.exe

hvax64.exe是AMD-V,hvix.64.exe是Intel-VT

intelvt

AMDVT

 

啟用了Hyper-V之後,將會使用Hypervisor去存取Hardware的CPU與Memory

接著,才會取啟動Host Server(在Hyper-V中稱為Parent Partition),又稱為父分割區

在啟用Hyper-V之後,Host將會處於下圖VM1中的位置,後續所建立的Guest OS,將會在VM2與VM3的位置

又稱為Child Partition,子分割區

hyper-v

 

從上圖可以看到,Child Partition都會需要安裝Driver才能存取像是Ethemet、Hard Drive、Time Sync…等等的一些裝置

 

然而會有很多VMWare ESX的使用者會說,在VMWare ESX裡的Guest OS就不需要安裝就能夠使用了

這是因為這兩者的Hypervisor的結構本身並不相同,VMWare ESX使用的是感知型的Hypervisor Drivers

所以會需要硬體支援(硬體廠商配合VMWare開發),但是Hyper-V則是Host有支援即可(有驅動就可以)

(下圖為VMWare ESX的Hypervisor)

VMWare

雖然VMWare可以在未安裝VM Tools的情況下運作,但是還是安裝後才能得到更多進階的功能

因為此篇主要是講解Hyper-V,在此就不對VMWare的部份有過多的說明囉~

下面這張圖,將說明啟用前跟啟用後的差異

hyper-v_enable

下圖,則是Parent跟Child之間的關係,在VMBus可溝通的情況下,將會使用Hypercall對Hypervisor進行I/O

hyper-v-role

Virtual Machine Worker Process(VMWP)就相當於是Guest OS的主機板

vmwp

VMWP會使用VMBUS、VID去使用Hypervisor API去對Hypervisor存取,取得Guest OS該使用的資源

112

12345

Virtualization infrastructure Driver其實就是%Systemroot%\System32\Drivers底下的winhv.sys

hvinf

VSC

當Guest OS在存取VHD時,則會透過VSC,經過VMBUS連接父分割區的VMBUS,由父分割區的VSP進行DISK I/O

storage

 

這是比較詳細的I/O運作邏輯

43

這是Driver透過VMBUS的對應

VMDevice

 

在此引用這個網站的圖片,來做一個簡單的圖解

http://www.msservermag.com.tw/technicwords/021128.aspx

01

微軟的MSDN中,有提供Hyper-V WMI Provider的文件可以參考

http://msdn.microsoft.com/en-us/library/cc136992(VS.85).aspx

 

在啟用Hyper-V後,會新增root\virtualization這個命名空間,我們可以透過PowerShell去查詢該命名空間底下所有的Object

指令是Get-Wmiobject –Namespace “root\virtualization” –Computer Hostname –list

WMI2

下圖這個範例,示範了如何透過WMI去查詢Guest OS的狀態

Get-WmiObject -Class Msvm_ComputerSystem -Namespace "root\virtualization" -ComputerName Hostname

其中的EnabledState就是回傳的狀態值,2代表正常

wmi

 

這邊看似沒甚麼了不起,GUI介面就可以得知的東西

呃…確實是如此,因為GUI介面就已經幫你寫好查詢的方法跟回傳,這裡只是大概講解Hyper-V Manager

是如何去取得Guest OS的狀態之類

 

但是如果是GUI介面所沒有的呢:P

或者你要用Job的方式從Host去控制Guest OS,而不是透過Guest OS的Job去控制呢?

這裡的命令,其實都是透過WMI去控制的

WMI3

接著來示範一個很奇特的範例,來驗證第一張圖,WMI的架構

我們先透過一個VBScript去使用Windows Script Host去呼叫CIMOM

然後,對Guest OS做鍵盤輸入的動作,首先先將下列VBScript存成PressKey.vbs

如對此VBScript不放心,您可以直接至Microsoft MSDN中複製

http://msdn.microsoft.com/en-us/library/cc136956(v=vs.85).aspx

 

001option explicit
002 
003dim objWMIService
004dim fileSystem
005const wmiSuccessful = 0
006 
007Main()
008 
009'-----------------------------------------------------------------
010' Main routine
011'-----------------------------------------------------------------
012Sub Main()
013     
014    dim computer, objArgs, vmName, computerSystem, keycode, keyboard
015     
016    set fileSystem = Wscript.CreateObject("Scripting.FileSystemObject")
017 
018    computer = "."
019    set objWMIService = GetObject("winmgmts:\\" & computer & "\root\virtualization")
020 
021    set objArgs = WScript.Arguments
022    if WScript.Arguments.Count = 2 then
023       vmName= objArgs.Unnamed.Item(0)
024       keycode = objArgs.Unnamed.Item(1)
025    else
026       WScript.Echo "usage: cscript PressKey.vbs vmName keycode"
027       WScript.Quit
028    end if
029     
030    set computerSystem = GetComputerSystem(vmName)
031    set keyboard = GetComputerKeyboard(computerSystem)
032 
033    if PressKey(keyboard, keycode) then
034 
035        WriteLog "Done"
036        WScript.Quit(0)
037    else
038        WriteLog "PressKey failed"
039        WScript.Quit(1)
040    end if
041 
042End Sub
043 
044'-----------------------------------------------------------------
045' Retrieve Msvm_VirtualComputerSystem from base on its ElementName
046'
047'-----------------------------------------------------------------
048Function GetComputerSystem(vmElementName)
049    dim query
050    On Error Resume Next
051    query = Format1("select * from Msvm_ComputerSystem where ElementName = '{0}'", vmElementName)
052    set GetComputerSystem = objWMIService.ExecQuery(query).ItemIndex(0)
053    if (Err.Number <> 0) then
054        WriteLog Format1("Err.Number: {0}", Err.Number)
055        WriteLog Format1("Err.Description:{0}",Err.Description)
056        WScript.Quit(1)
057    end if
058End Function
059 
060 
061'-----------------------------------------------------------------
062' Retrieve Msvm_Keyboard from given computer system
063'
064'-----------------------------------------------------------------
065Function GetComputerKeyboard(computerSystem)
066    dim query
067    On Error Resume Next
068    query = Format1("ASSOCIATORS OF {{0}} WHERE resultClass = Msvm_Keyboard", computerSystem.Path_.Path)
069    set GetComputerKeyboard = objWMIService.ExecQuery(query).ItemIndex(0)
070    if (Err.Number <> 0) then
071        WriteLog Format1("Err.Number: {0}", Err.Number)
072        WriteLog Format1("Err.Description:{0}",Err.Description)
073        WScript.Quit(1)
074    end if
075End Function
076 
077'-----------------------------------------------------------------
078' Press the key with the given key code on the given keyboard
079'-----------------------------------------------------------------
080Function PressKey(keyboard, keyCode)
081    WriteLog Format2("PressKey({0}, {1})", keyboard.ElementName, keyCode)
082     
083    dim objInParam, objOutParams
084     
085    PressKey = false
086    set objInParam = keyboard.Methods_("PressKey").InParameters.SpawnInstance_()
087    objInParam.keyCode = keyCode
088 
089    set objOutParams = keyboard.ExecMethod_("PressKey", objInParam)
090 
091    if objOutParams.ReturnValue = wmiSuccessful then
092        WriteLog Format2("The key with code '{0}' is typed on {1}.", keyCode, keyboard.ElementName)
093        PressKey = true
094    end if
095 
096End Function
097 
098'-----------------------------------------------------------------
099' Create the console log files.
100'-----------------------------------------------------------------
101Sub WriteLog(line)
102    dim fileStream
103    set fileStream = fileSystem.OpenTextFile(".\PressKey.log", 8, true)
104    WScript.Echo line
105    fileStream.WriteLine line
106    fileStream.Close
107 
108End Sub
109 
110 
111'------------------------------------------------------------------------------
112' The string formatting functions to avoid string concatenation.
113'------------------------------------------------------------------------------
114Function Format2(myString, arg0, arg1)
115    Format2 = Format1(myString, arg0)
116    Format2 = Replace(Format2, "{1}", arg1)
117End Function
118 
119'------------------------------------------------------------------------------
120' The string formatting functions to avoid string concatenation.
121'------------------------------------------------------------------------------
122Function Format1(myString, arg0)
123    Format1 = Replace(myString, "{0}", arg0)
124End Function

 

接著我們會需要這張表去對應Virtial Key相對應的Uint32的值

http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx

 

這張表的值是16進位,將其換算成十進位後,加上256,會可以輸入該值到Guest OS中

像範例中,我會Daniel-AD這部Guest OS輸入鍵盤324,d這個字母在表列中為0x44

也就是256+68=324,接著他就會在Guest OS中輸入d這個字母

WMI4

 

你也可以透過Powershell去轉換這個數值

PowerShell的語法function To-UInt32{[UInt32]("0x{0:x}" -f $args[0])+256}

這可以新增一個To UInt32的轉換方法

接著可以透過To-UInt32 0x44去取得相對應的值

WMI5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值