Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他
          
          
CPUIDの変更方法
          VirtualBoxを使用するとゲストOSに対してホストPCと異なるCPUID値を与えることができる。
たとえば、SSE2を未サポートにしたり、CPU名称を変更したりできる。
以下 VirtualBox Version 5.0.8 r 103449での動作について解説する。
CPUIDの変更はVBoxManageコマンドを使用する。
          
ファンクション番号は変更したいCPUIDのファンクション番号、EAX~EDXはCPUID命令が出力する各レジスタの値を16進数で記述する。
サポートするファンクション番号の範囲は、基本ファンクションがファンクション0のEAXレジスタ、拡張ファンクションがファンクション0x80000000のEAXレジスタで設定する。
CPUIDの値を初期値に戻すときは、以下の様に入力する
マルチブート環境はインストールがCドライブとは限らないので、環境変数を使用すると便利である。 環境変数VBOX_MSI_INSTALL_PATHはVirtualBoxがインストールされている場合に定義され、インストールフォルダーを示している。(通常は、C:¥Program Files¥Oracle¥VirtualBox¥が定義されている)
環境変数の前後に%を入れるとバッチファイルで環境変数の値を参照できる。インストールフォルダーは通常Program Filesの下である。Program Filesの様に途中で空白があると、コマンド名がProgramと解釈されてしまうので、以下の様に全体をダブルコーテーションでくくる。
これを実行すると仮想環境Windows VistaのCPUの名称がAthlon 64 3200+となる。 同じ名前を何回も記述しなくても良い様に環境変数VM_NAMEに名前を定義し各行で参照している。
pauseはバッチファイルが一瞬で実行され実行結果が分からなくなるので、キー入力があるまでバッチファイルで起動されたコマンドプロンプトを閉じないようにするためである。 上記の内容のバッチファイルを仮想環境を停止した状態で実行し仮想環境を起動すると下図のようにIntel入ってるPC(Intel Core i7-3820)で実行しているにもかかわらずゲストOSではIntel入っていない(AMD Athlon(tm) 64 Processor 3200+)になる。
下図のWindows Vistaのログインユーザー名は着色してわからないようにしています。
          
          
バッチファイルでCPU名に対応しているのが赤で示した部分です。
以下の様にアスキーコードで4文字(4byte)ずつリトルエンディアンで記述します。すなわち4文字単位で文字順を逆にしアスキーコードを16進数で記述すればOKです。文字列の最後は00である必要があります。
最大で00を含めて48文字となります。
        たとえば、SSE2を未サポートにしたり、CPU名称を変更したりできる。
以下 VirtualBox Version 5.0.8 r 103449での動作について解説する。
CPUIDの変更はVBoxManageコマンドを使用する。
VBoxManage modifyvm 名前 --cpuidset ファンクション番号 EAX EBX ECX EDXファンクション番号は変更したいCPUIDのファンクション番号、EAX~EDXはCPUID命令が出力する各レジスタの値を16進数で記述する。
サポートするファンクション番号の範囲は、基本ファンクションがファンクション0のEAXレジスタ、拡張ファンクションがファンクション0x80000000のEAXレジスタで設定する。
CPUIDの値を初期値に戻すときは、以下の様に入力する
VBoxManage modifyvm 名前 --cpuidremoveallマルチブート環境はインストールがCドライブとは限らないので、環境変数を使用すると便利である。 環境変数VBOX_MSI_INSTALL_PATHはVirtualBoxがインストールされている場合に定義され、インストールフォルダーを示している。(通常は、C:¥Program Files¥Oracle¥VirtualBox¥が定義されている)
環境変数の前後に%を入れるとバッチファイルで環境変数の値を参照できる。インストールフォルダーは通常Program Filesの下である。Program Filesの様に途中で空白があると、コマンド名がProgramと解釈されてしまうので、以下の様に全体をダブルコーテーションでくくる。
"%VBOX_MSI_INSTALL_PATH%VBoxManage" modifyvm 名前 --cpuidset ファンクション番号 EAX EBX ECX EDXこれを実行すると仮想環境Windows VistaのCPUの名称がAthlon 64 3200+となる。 同じ名前を何回も記述しなくても良い様に環境変数VM_NAMEに名前を定義し各行で参照している。
set VM_NAME="Windows Vista"
"%VBOX_MSI_INSTALL_PATH%VBoxManage" modifyvm %VM_NAME% --cpuidset 80000000 80000004 68747541 444D4163 69746E65
"%VBOX_MSI_INSTALL_PATH%VBoxManage" modifyvm %VM_NAME% --cpuidset 80000002 20444D41 6C687441 74286E6F 3620296D
"%VBOX_MSI_INSTALL_PATH%VBoxManage" modifyvm %VM_NAME% --cpuidset 80000003 72502034 7365636F 20726F73 30303233
"%VBOX_MSI_INSTALL_PATH%VBoxManage" modifyvm %VM_NAME% --cpuidset 80000004 0000002B 00000000 00000000 00000000
set VM_NAME=
pause
pauseはバッチファイルが一瞬で実行され実行結果が分からなくなるので、キー入力があるまでバッチファイルで起動されたコマンドプロンプトを閉じないようにするためである。 上記の内容のバッチファイルを仮想環境を停止した状態で実行し仮想環境を起動すると下図のようにIntel入ってるPC(Intel Core i7-3820)で実行しているにもかかわらずゲストOSではIntel入っていない(AMD Athlon(tm) 64 Processor 3200+)になる。
下図のWindows Vistaのログインユーザー名は着色してわからないようにしています。

バッチファイルでCPU名に対応しているのが赤で示した部分です。
以下の様にアスキーコードで4文字(4byte)ずつリトルエンディアンで記述します。すなわち4文字単位で文字順を逆にしアスキーコードを16進数で記述すればOKです。文字列の最後は00である必要があります。
最大で00を含めて48文字となります。
  D M A  l h t A  t ) n o   6  ) m
20444D41 6C687441 74286E6F 3620296D
r P   4  s e c o    r o s  0 0 2 3
72502034 7365636F 20726F73 30303233
      +
0000002B 00000000 00000000 00000000          
            
              アスキーコード表
             
            
              
               
              0 
              1 
              2 
              3 
              4 
              5 
              6 
              7 
              8 
              9 
              A 
              B 
              C 
              D 
              E 
              F 
             
            
              2 
              
               
              ! 
              " 
              # 
              $ 
              % 
              & 
              ' 
              ( 
              ) 
              * 
              + 
              , 
              - 
              . 
              / 
             
            
              3 
              0 
              1 
              2 
              3 
              4 
              5 
              6 
              7 
              8 
              9 
              : 
              ; 
              < 
              = 
              > 
              ? 
             
            
              4 
              @ 
              A 
              B 
              C 
              D 
              E 
              F 
              G 
              H 
              I 
              J 
              K 
              L 
              M 
              N 
              O 
             
            
              5 
              P 
              Q 
              R 
              S 
              T 
              U 
              V 
              W 
              X 
              Y 
              Z 
              [ 
              \ 
              ] 
              ^ 
              _ 
             
            
              6 
              ` 
              a 
              b 
              c 
              d 
              e 
              f 
              g 
              h 
              i 
              j 
              k 
              l 
              m 
              n 
              o 
             
            
              7 
              p 
              q 
              r 
              s 
              t 
              u 
              v 
              w 
              x 
              y 
              z 
              { 
              | 
              } 
              ~ 
               
             
            
              A 
                
              。 
              「 
              」 
              、 
              ・ 
              ヲ 
              ァ 
              ィ 
              ゥ 
              ェ 
              ォ 
              ャ 
              ュ 
              ョ 
              ッ 
             
            
              B 
              ー 
              ア 
              イ 
              ウ 
              エ 
              オ 
              カ 
              キ 
              ク 
              ケ 
              コ 
              サ 
              シ 
              ス 
              セ 
              ソ 
             
            
              C 
              タ 
              チ 
              ツ 
              テ 
              ト 
              ナ 
              ニ 
              ヌ 
              ネ 
              ノ 
              ハ 
              ヒ 
              フ 
              ヘ 
              ホ 
              マ 
             
            
              D 
              ミ 
              ム 
              メ 
              モ 
              ヤ 
              ユ 
              ヨ 
              ラ 
              リ 
              ル 
              レ 
              ロ 
              ワ 
              ン 
              ゙ 
              ゚ 
             
          
          仮想環境なので意味はありませんが、8088、Z80、6809、Xeon、Crusoe TM5600,Pentium 5 10GHzなどCPU名や人名などアスキー文字(Windows Vistaでは半角カタカナも正常動作した)に限られますが変更できます。
          各種CPUのCPUIDの値を調べる場合は以下のページが便利です。
          http://users.atw.hu/instlatx64/ リンク先のCPUID Dumpをクリックすると各CPUのCPUIDが参照できます。
          またCPUIDのファンクションについてはIntelのデーターシートの他以下のリンク先を参照しました。
          http://sandpile.org/x86/cpuid.htm
          以下にいくつかのCPU用のバッチファイルを用意しています。ダウンロードし仮想環境名を変更して実行するとCPUIDが変更できます。
        CPUIDの変更の影響
          ゲストOSにおいて変更したCPUIDがどのように影響するか調べた。
ここではCPU i7-3820で動作するVirtualBoxのゲストOSがWindows Vistaであり、割り当てCPU数が4の場合のゲストマシーンのCPUIDを変更した場合の動作について示す。
          
            
          
          
            
          
          
            
          
          
            
          ※ファンクション最大の基本は基本ファンクションで指定できる最大値を示す。
※ファンクション最大の拡張は拡張ファンクションで指定できる最大値から0x80000000を引いた値を示す。(例えばCeleron 2.00GHzでは0x80000000+0x04=0x80000004が指定できる最大値となる。)記載なき場合は拡張ファンクションを使用できないことを示す。
以上よりCPUIDの基本ファンクションが4以上をサポートしている場合は、L2以降はホストCPUのCPUIDがそのまま反映されそれにゲストCPU数が影響している。
CPUIDの基本ファンクションが4以上をサポートしているPentium4系についてはL1キャッシュも影響を受けている。
i7-3820がホストCPUの場合、CPUIDのファンクション1の結果、ハイパースレッドがON(EDXのビット28が1)で基本ファンクションが4以上をサポートしている場合、L1命令キャッシュが半分の容量となる。
ゲストOSではCPUIDでPentium2相当にしてもハイパースレッドがONとなっていた。
VBoxManage modifyvmコマンドによりゲストCPUのCPUIDの変更は基本ファンクションでは0xb以降はエラーとなり無視されるが、0xb以降が必要な場合は、VirtualBoxが自動的にCPUID値を提供している。またホストCPUがサポートしているファンクション以上のCPUIDが使用できている。(ホストCPUの基本ファンクションが0xbまででもCPUID値で0x14とすればゲストでは0x14まで使用できる可能性がある。)
ホストCPUがサポートしている機能であればCPUIDで使用可能としていればゲストCPUでも使用できる。ホストCPUがサポートしていない機能は、VirtualBoxがCPUID値を修正して未サポートとしている。(ホストでAVX2が未サポートであればCPUIDでAVX2をONしてもゲストCPUでは未サポートとなる)
ブランド情報(ストリング、ID等)およびプロセッサのステッピング、モデル、ファミリー等は設定したCPU値が反映される。
CPUID値でハイパースレッドをONにしコアあたりのスレッド数を2にしてもハイパースレッドがONの1コア当り1スレッドのCPUに変換される。
したがってゲストOSに割り当てるCPU数が同じであればPentium4とPentiumDおよびCore2DuoとCore2Quadやi3~i7は同一となる。
VirtualBoxでは物理パッケージが複数個存在する設定はできないようなので1つの物理パッケージの中のコア数が変化することになる。)
従って、マルチコアCPUが存在しない世代のCPUであれば本来複数ソケットとなるはずがマルチコアとしてエミュレーションされることとなる。
        
      ここではCPU i7-3820で動作するVirtualBoxのゲストOSがWindows Vistaであり、割り当てCPU数が4の場合のゲストマシーンのCPUIDを変更した場合の動作について示す。
| CPU | ホストCPU | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| 構成 | キャッシュ(1コア当り) | ファンクション最大 | |||||||
| コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | 基本 | 拡張 | |
| i7-3820 3.60GHz | 4 | 2 | 32k | 32k | 256k | 2560k | 0x0d | 0x08 | |
| CPU | シミュレーションされるCPU | ゲストCPU | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 構成 | キャッシュ(1コア当り) | ファンクション最大 | 構成 | キャッシュ(1コア当り) | |||||||||||||
| コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | 基本 | 拡張 | ソケット | コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | |
| Celeron 2.00GHz | 1 | 1 | 12kμ | 8k | 128k | 0x02 | 0x04 | 1 | 4 | 1 | 12kμ | 8k | 128k | ||||
| Pentium4 3.40GHz | 1 | 2 | 12kμ | 16k | 2048k | 0x06 | 0x08 | 1 | 4 | 1 | 16k | 16k | 256k | 10240k | |||
| PentiumD 3.40GHz | 2 | 1 | 12kμ | 16k | 2048k | 0x06 | 0x08 | 1 | 4 | 1 | 16k | 16k | 256k | 10240k | |||
| Core2 6320 1.86GHz | 2 | 1 | 32k | 32k | 2048k | 0x0a | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | |||
| Core2 Q8200 2.33GHz | 4 | 1 | 32k | 32k | 1024k | 0x0a | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | |||
| i7 CPU 870 2.93GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0b | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| i7-4770 3.40GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0d | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| i3-2100 3.10GHz | 2 | 2 | 32k | 32k | 256k | 1536k | 0x0d | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| i7-2600 3.40GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0d | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| i7-5775C 3.30GHz | 4 | 2 | 32k | 32k | 256k | 1536k | 32768k | 0x14 | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | |
| i7-6700K 4.00GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x16 | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| i5-2400 3.10GHz | 4 | 1 | 32k | 32k | 256k | 1536k | 0x0d | 0x08 | 1 | 4 | 1 | 16k | 32k | 256k | 10240k | ||
| Atom D2701 2.13GHz | 2 | 2 | 32k | 24k | 512k | 0x0a | 0x08 | 1 | 4 | 1 | 16k | 24k | 256k | 10240k | |||
| Pentium2 450MHz | 1 | 1 | 16k | 16k | 512k | 0x02 | 1 | 4 | 1 | 16k | 16k | 512k | |||||
| MMX Pentium | 1 | 1 | 16k | 16k | 0x01 | 1 | 4 | 1 | 16k | 16k | |||||||
| CPU | ホストCPU | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| 構成 | キャッシュ(1コア当り) | ファンクション最大 | |||||||
| コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | 基本 | 拡張 | |
| i3 M370 2.40GHz | 2 | 2 | 32k | 32k | 256k | 1536k | 0x0b | 0x08 | |
| CPU | シミュレーションされるCPU | ゲストCPU | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 構成 | キャッシュ(1コア当り) | ファンクション最大 | 構成 | キャッシュ(1コア当り) | |||||||||||||
| コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | 基本 | 拡張 | ソケット | コア | スレッド(1コア当り) | L1 Inst | L1 Data | L2 | L3 | L4 | |
| Celeron 2.00GHz | 1 | 1 | 12kμ | 8k | 128k | 0x02 | 0x04 | 1 | 4 | 1 | 12kμ | 8k | 128k | ||||
| i7 CPU 870 2.93GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0b | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | ||
| Core2 6320 1.86GHz | 2 | 1 | 32k | 32k | 2048k | 0x0a | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | |||
| Core2 Q8200 2.33GHz | 4 | 1 | 32k | 32k | 1024k | 0x0a | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | |||
| i3-2100 3.10GHz | 2 | 2 | 32k | 32k | 256k | 1536k | 0x0d | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | ||
| i7-2600 3.40GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0d | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | ||
| i7-4770 3.40GHz | 4 | 2 | 32k | 32k | 256k | 2048k | 0x0d | 0x08 | 1 | 4 | 1 | 32k | 32k | 256k | 3072k | ||
※ファンクション最大の拡張は拡張ファンクションで指定できる最大値から0x80000000を引いた値を示す。(例えばCeleron 2.00GHzでは0x80000000+0x04=0x80000004が指定できる最大値となる。)記載なき場合は拡張ファンクションを使用できないことを示す。
以上よりCPUIDの基本ファンクションが4以上をサポートしている場合は、L2以降はホストCPUのCPUIDがそのまま反映されそれにゲストCPU数が影響している。
CPUIDの基本ファンクションが4以上をサポートしているPentium4系についてはL1キャッシュも影響を受けている。
i7-3820がホストCPUの場合、CPUIDのファンクション1の結果、ハイパースレッドがON(EDXのビット28が1)で基本ファンクションが4以上をサポートしている場合、L1命令キャッシュが半分の容量となる。
ゲストOSではCPUIDでPentium2相当にしてもハイパースレッドがONとなっていた。
VBoxManage modifyvmコマンドによりゲストCPUのCPUIDの変更は基本ファンクションでは0xb以降はエラーとなり無視されるが、0xb以降が必要な場合は、VirtualBoxが自動的にCPUID値を提供している。またホストCPUがサポートしているファンクション以上のCPUIDが使用できている。(ホストCPUの基本ファンクションが0xbまででもCPUID値で0x14とすればゲストでは0x14まで使用できる可能性がある。)
ホストCPUがサポートしている機能であればCPUIDで使用可能としていればゲストCPUでも使用できる。ホストCPUがサポートしていない機能は、VirtualBoxがCPUID値を修正して未サポートとしている。(ホストでAVX2が未サポートであればCPUIDでAVX2をONしてもゲストCPUでは未サポートとなる)
ブランド情報(ストリング、ID等)およびプロセッサのステッピング、モデル、ファミリー等は設定したCPU値が反映される。
CPUID値でハイパースレッドをONにしコアあたりのスレッド数を2にしてもハイパースレッドがONの1コア当り1スレッドのCPUに変換される。
したがってゲストOSに割り当てるCPU数が同じであればPentium4とPentiumDおよびCore2DuoとCore2Quadやi3~i7は同一となる。
VirtualBoxでは物理パッケージが複数個存在する設定はできないようなので1つの物理パッケージの中のコア数が変化することになる。)
従って、マルチコアCPUが存在しない世代のCPUであれば本来複数ソケットとなるはずがマルチコアとしてエミュレーションされることとなる。
      Copyright (C) 2012 山本ワールド All Rights Reserved.
    
    
  