VirtualBoxのWindows 8ホストにXPゲストがいます。ゲストは、ホストと透過的に同じプロセッサを表示します(i5 2500k)。ただし、ほとんどのインストーラーはこのプロセッサーを認識せず、サポートされていないプロセッサーの表示を続行できません。
ゲストをだましてこれを古いプロセッサだと思わせる方法はありますか?VMWareにCPUマスキング機能があったことを正しく思い出せば、virtualboxに似たようなものがありますか?
VirtualBoxのWindows 8ホストにXPゲストがいます。ゲストは、ホストと透過的に同じプロセッサを表示します(i5 2500k)。ただし、ほとんどのインストーラーはこのプロセッサーを認識せず、サポートされていないプロセッサーの表示を続行できません。
ゲストをだましてこれを古いプロセッサだと思わせる方法はありますか?VMWareにCPUマスキング機能があったことを正しく思い出せば、virtualboxに似たようなものがありますか?
回答:
VBoxInternal/CPUM/HostCPUID
仮想マシンの追加データを設定する必要があります。これにより、VirtualBoxはCPUID命令のカスタム結果をゲストに報告します。EAXレジスタの値に応じて、この命令はプロセッサに関する情報を返します-ベンダー、タイプ、ファミリ、ステッピング、ブランド、キャッシュサイズ、機能(MMX、SSE、SSE2、PAE、HTT)などのようなもの。あなたがマングルすると、ゲストをだます可能性が高くなります。
このvboxmanage setextradata
コマンドを使用して、仮想マシンを構成できます。例えば、
vboxmanage setextradata WinXP VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x50202952
EAXを80000003に設定して呼び出した場合、CPUIDはEBXレジスターに50202952を返します。(今後、16進数は0xNNまたはNNhとして書き込まれます。)
EAXが0(またはAMDでは80000000h)の場合、CPUIDはベンダーをレジスタEBX、EDX、ECXのASCII文字列として返します(順序に注意してください)。AMD CPUの場合、次のようになります。
| Register | Value | Description |
|----------|------------|--------------------------------|
| EBX | 6874_7541h | The ASCII characters "h t u A" |
| ECX | 444D_4163h | The ASCII characters "D M A c" |
| EDX | 6974_6E65h | The ASCII characters "i t n e" |
(AMD CPUID仕様のサブセクション「CPUID Fn0000_0000_E」から取得)
EBX、EDX、ECXを連結すると、が得られAuthenticAMD
ます。
Bashと従来のUnixユーティリティがある場合は、次のコマンドで簡単にベンダーを設定できます。
vm='WinXP' # UUID works as well
# The vendor string needs to have 12 characters!
vendor='AuthenticAMD'
if [ ${#vendor} -ne 12 ]; then
exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }
registers=(ebx edx ecx)
for (( i=0; i<${#vendor}; i+=4 )); do
register=${registers[$(($i/4))]}
value=`echo -n "${vendor:$i:4}" | ascii2hex`
# set value to an empty string to reset the CPUID, i.e.
# value=""
for eax in 00000000 80000000; do
key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
vboxmanage setextradata "$vm" $key $value
done
done
EAXが80000002h、80000003h、80000004hの場合、CPUIDはレジスタEAX、EBX、ECX、EDXにブランド文字列の16個のASCII文字を返し、合計3 * 16 = 48文字です。文字列はヌル文字で終了します。この機能はPentium 4プロセッサで導入されたことに注意してください。これは、ブランド文字列がPentium 4プロセッサでどのように見えるかです。
| EAX Input Value | Return Values | ASCII Equivalent |
|-----------------|-----------------|------------------|
| 80000002h | EAX = 20202020h | " " |
| | EBX = 20202020h | " " |
| | ECX = 20202020h | " " |
| | EDX = 6E492020h | "nI " |
|-----------------|-----------------|------------------|
| 80000003h | EAX = 286C6574h | "(let" |
| | EBX = 50202952h | "P )R" |
| | ECX = 69746E65h | "itne" |
| | EDX = 52286D75h | "R(mu" |
|-----------------|-----------------|------------------|
| 80000004h | EAX = 20342029h | " 4 )" |
| | EBX = 20555043h | " UPC" |
| | ECX = 30303531h | "0051" |
| | EDX = 007A484Dh | "☠zHM" |
|-----------------|-----------------|------------------|
(Intel Architecture Instruction Set Extensions Programming Referenceのサブセクション2.9「CPUID命令」、表2-30から引用。.はヌル文字(数値0)です。)
結果をまとめると、が得られ Intel(R) Pentium(R) 4 CPU 1500MHz☠
ます。
Bashと従来のUnixユーティリティがある場合は、次のコマンドでブランドを簡単に設定できます。
vm='WinXP' # UUID works as well
# The brand string needs to have 47 characters!
# The null terminator is added automatically
brand=' Intel(R) Pentium(R) 4 CPU 1500MHz'
if [ ${#brand} -ne 47 ]; then
exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }
eax_values=(80000002 80000003 80000004)
registers=(edx ecx ebx eax)
for (( i=0; i<${#brand}; i+=4 )); do
eax=${eax_values[$((${i} / 4 / 4))]}
register=${registers[$((${i} / 4 % 4 ))]}
key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
value=`echo -n "${brand:$i:4}" | ascii2hex`
# set value to an empty string to reset the CPUID, i.e.
# value=""
vboxmanage setextradata "$vm" $key $value
done
Windowsコマンドプロンプトがある場合は、次を実行してブランドをIntel(R) Core(TM)2 CPU 6600 @ 2.40 GHz
1に設定できます。
set vm=your-vm-name-or-uuid
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/eax 0x65746e49
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ebx 0x2952286c
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ecx 0x726f4320
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/edx 0x4d542865
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/eax 0x43203229
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x20205550
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ecx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/edx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/eax 0x30303636
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ebx 0x20402020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ecx 0x30342e32
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/edx 0x007a4847
1HostCPUID
の値は、VirtualBoxのバグ報告から採取した#7865。
's/ //g'
--cpuid
サブコマンドにはEAXレジスタの値が必要なので、ベンダーにとってはそれほどうまくいきません。
これは、必要な設定を推測するのではなく、ホストCPUを特定のCPUとして正確にマスカレードできるアプローチです。そのホストCPUでVirtualBoxを実行しているマシンにアクセスして、そのcpuid
レジスタをダンプできるようにする必要があります(モデルとして実際のCPUのアーキテクチャにかなり近いアーキテクチャを選択することをお勧めします)。手元に持っていない場合は、尋ねることができます(たとえば、Redditで成功しました)。
エミュレートするCPUから「モデル」ファイルを作成します。
vboxmanage list hostcpuids > i7_6600U
次のスクリプトを実行して、モデルファイル(i7_6600U
ここ)をVBox VMの定義(ここ)にロードしますmy_vm_name
。
#!/bin/bash
vm=my_vm_name
model_file=i7_6600U
egrep -e '^[[:digit:]abcdef]{8} ' $model_file |
while read -r line; do
leaf="0x`echo $line | cut -f1 -d' '`"
# VBox doesn't like applying leaves between the below boundaries so skip those:
if [[ $leaf -lt 0x0b || $leaf -gt 0x17 ]]; then
echo "Applying: $line"
vboxmanage modifyvm $vm --cpuidset $line
fi
done
これで、VMを実行して、マスカレードCPUを楽しむことができます(注:上記のスクリプトを実行する必要があるのは1回だけです)。
CPUマスカレードをロールバックする必要がある場合vboxmanage modifyvm $vm --cpuidremove $leaf
は、上記のループ内の各リーフに使用できます(man vboxmanage
友人です)。
これは、私にとっては数か月間、VBox 5.1.22を実行しているUbuntu 17.04ホストでKaby Lake CPU(i7_7500U)をSkylakeのもの(i7_6600U)に見せかけながら、完璧に機能しています。上記の小さなbashスクリプトと同等のOSを作成できる場合、このアプローチはどのホストOSでも動作するはずです。
0000000b
し、00000017
(包括的に)とを1つずつ、それらを実行しているvboxmanage modifyvm my_vm_name --cpuidset <line>
、それは一回限りだと、このように手で簡単に行うことができます。