BitVisor を VMware Workstation で動かしてみた(Windows 10 編)

これは BitVisor Advent Calendar 11 日目の記事です(たぶん)
# はじめに
これまでも BitVisor は VMware Workstation 上で動かした記事があるのですが、ホスト OS が Linux か macOS (macOS だと VMware fusion) である記事だけだったように思うので、今回は Windows 10 をホスト OS にして動作確認してみたいと思います。

* 参考: [VMwareを利用したBitVisor開発環境 - Qiita] (https://qiita.com/mmi/items/16c63ff4e6b09c64977f) ... macOS で動作させている記事
* 参考: [VMWare GDB stubを利用したBitVisorのデバッグ - Qiita](https://qiita.com/mmi/items/d3ddb0ca468a7c5e6337) ... Linux で動作させている記事

## 結論
動きました。
ただし、ちゃんと検証はしていませんが、Hyper-V や WSL2, Docker for Windows との共存は難しいかもしれないです。
以下では、今回ためした方法について書いていきます。

# 動作環境
* PC: Microsoft Surface Pro 7
* ホスト OS
  * Edition: Windows 10 Home
  * version: 20H2
  * OS build: 19042.685
* ゲスト OS: Fedora 33 Server

# 手順
## VMware のインストール
以下からダウンロードしてインストールしました。


## VMware で Nested virtualization を有効にするための Windows の設定
残念ながら、VMware Workstation の Nested Virtualization (VT-x の仮想化) を有効にするためには、現状 Hyper-V ハイパバイザを無効にする必要があるようです。

* 参考: [Solved: VMware Workstation does not support nested virtual... - VMware Technology Network VMTN](
https://www.vmware.com/jp/products/workstation-player/workstation-player-evaluation.html)

注意として、Hyper-V ハイパバイザを無効にしてしまうと、これを使っている WSL2,  Docker for Windows,  Hyper-V などが動かなくなってしまうと思います (未検証)
Windows の仮想化周りの機能については、以下の記事がわかりやすかったです。

* 参考: [WSL2とHyper-Vの関係 - Qiita](https://qiita.com/matarillo/items/ca1eecf8f9a3cd76f9ce)

設定方法ですが、管理者権限で Powershell を起動し、以下のコマンドを実行した後、再起動するとできます。

```powershell
> bcdedit.exe -set hypervisorlaunchtype off
> # 設定内容の確認
> bcdedit.exe -enum | Select-String 'hypervisorlaunchtype'

hypervisorlaunchtype    Off

```

また、Hyper-V ハイパバイザを再び有効にするには `bcdedit.exe -set hypervisorlaunchtype auto` とするとよいようです。
 
* 参考: [Hyper-VのON・OFFを簡単に自動化すっぞ！！ - Qiita](https://qiita.com/dodonki1223/items/75bd5171e2f2193c9977)

## VM の作成およびゲスト OS のインストール

インストールした VMware Workstation で VM を作成し、ゲスト OS をインストールします。詳細は割愛しますが、[ここ](https://getfedora.org/ja/server/download/)からダウンロードした `Fedora 33: Standard ISO image for x86_64` を使って Fedora 33 Server をインストールしました。
VMware には easy install なる仕組みがあるらしく、特にこだわりがなければ　VM 作成時に ISO の選択とユーザー名およびルートパスワードの入力だけで VM の作成から OS の インストールまで終わりました。楽でいいですね。

## VM の Nested Virtualization 有効化

VM の作成ができたら、VM の設定を変更し、Nested Virtualization を有効にします。
作成した VM の「仮想マシン設定の編集」から以下のように「プロセッサ」を選択し、「Intel VT-x/EPT または AMD-V RVI を仮想化」という項目にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59503/b8c3a467-2c80-b84f-7837-62e7db7b32ad.png)


## BitVisor のコンパイル
次に、BitVisor をビルドおよびインストールをします。
今回は、BIOS ブートの grub で起動します。
ちなみに、VMware で特に設定せずに VM を作成すると BIOS ブートになるようです。

* `git` or `hg`, `make`, `gcc`, `newt` パッケージをインストール
* git or hg で bitvisor を clone
    * git なら https://github.com/matsu/bitvisor.git からクローン
    * hg なら http://hg.code.sf.net/p/bitvisor/code からクローン
* make config
  * dbgsh の動作に不要そうなものは無効にしています。付録に .config を貼ったので、詳細はそちらを確認ください。
* make
* /boot/ に bitvisor.elf をコピー


コマンドでは以下のようになります(面倒だったので全部 root で実行しています)

```
# yum update
# yum install git make gcc newt
# git clone https://github.com/matsu/bitvisor.git
# cd bitvisor
# make config
# make
# cp bitvisor.elf /boot/
```

## BitVisor の起動
本当は grub にエントリーを追加して... とやりたかったのですが、Fedora 33 では Bootloader Spec (BLS) なる仕組みで grub が制御されているらしく、linux 以外のブートエントリーの作成方法がよくわかりませんでした...

* 参考: [fedora 30からgrubの仕様が変わったのでφ(..)メモメモ - φ(・・*)ゞ ｳｰﾝ　カーネルとか弄ったりのメモ](https://kernhack.hatenablog.com/entry/2019/04/09/233227)
* 参考: [Changes/BootLoaderSpecByDefault - Fedora Project Wiki](https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault)

少し調べて面倒になったので、今回は grub 起動時に手で起動コマンドを打ちました。

以下で `c` を押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59503/902dccee-a0a3-1cdc-6287-1a67dc82b4cc.png)

以下のように入力して、Enter で OK です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59503/b6ddd308-ae34-5819-c208-248e68b5d826.png)

入力しているコマンドは

```
multiboot (hd0,msdos2)/bitvisor.elf
boot
```
です。
パーティションは (hd0,msdos2) は作成したディスクによって違うかもしれません。このシェルでは `ls (hd0,msdos2)/` (スラッシュまで入力) するとパーティションの中身が見れるので、それで確認するとよいと思います。

この後、緑色の BitVisor のログが出たのち、また grub のメニューがでますので、ゲスト OS のエントリーを選択し起動するとよいです。

## 動作確認
BitVisor の dbgsh が動作していることを確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59503/d003e96d-97f7-3d4e-eca6-979024e45e3e.png)

# おわりに
BitVisor on VMware Workstation on Windows 10 が動作するか試してみました。無事に動作しましたが、Hyper-V ハイパバイザを使ったツールとの共存には課題がありそうです。

# 付録: .config
```
CONFIG_64=1#64bit VMM
CONFIG_DEBUG_GDB=0#gdb remote debug support (32bit only)
CONFIG_TTY_SERIAL=0#VMM uses a serial port (COM1) for output
CONFIG_TTY_X540=0#VMM output to LAN
CONFIG_CPU_MMU_SPT_1=0#Shadow type 1 (very slow and stable)
CONFIG_CPU_MMU_SPT_2=0#Shadow type 2 (faster and unstable)
CONFIG_CPU_MMU_SPT_3=1#Shadow type 3 (faster and unstable)
CONFIG_CPU_MMU_SPT_DISABLE=0#Disable SPT (fast, insecure and no MMIO)
CONFIG_CPU_MMU_SPT_USE_PAE=1#Shadow page table uses PAE
CONFIG_PS2KBD_F11PANIC=0#Panic when F11 is pressed (PS/2 only)
CONFIG_PS2KBD_F12MSG=1#Print when F12 is pressed (PS/2 only)
CONFIG_DBGSH=1#Debug shell access from guest
CONFIG_STATUS=0#Provide VMM status for guest
CONFIG_LOG_TO_GUEST=0#Log to guest memory
CONFIG_LOG_TO_IEEE1394=0#Log to IEEE 1394 host
CONFIG_ATA_DRIVER=0#Enable ATA driver
CONFIG_NVME_DRIVER=0#Enable NVMe driver
CONFIG_STORAGE=0#Enable storage process/encryption
CONFIG_STORAGE_IO=0#Enable storage IO interface
CONFIG_CRYPTO=0#Crypto library
CONFIG_VPN=0#Enable IPsec VPN Client
CONFIG_USB_DRIVER=0#Enable USB driver
CONFIG_SHADOW_UHCI=0#Shadow UHCI(USB1) transfers
CONFIG_SHADOW_EHCI=0#Shadow EHCI(USB2) transfers
CONFIG_SHADOW_XHCI=0#Shadow xHCI(USB3) transfers
CONFIG_HANDLE_USBMSC=0#Handle USB mass storage class devices
CONFIG_HANDLE_USBHUB=0#Handle USB hub class devices
CONFIG_CONCEAL_USBCCID=0#Conceal USB ccid class device
CONFIG_PS2KBD_F10USB=0#Run a test for USB ICCD when F10 pressed
CONFIG_PS2KBD_F12USB=0#Dump EHCI async. list when F12 pressed
CONFIG_IEEE1394_CONCEALER=0#Conceal OHCI IEEE 1394 host controllers
CONFIG_ACPI_DSDT=1#Parse ACPI DSDT
CONFIG_DISABLE_SLEEP=0#Disable ACPI S2 and S3
CONFIG_ENABLE_ASSERT=1#Enable checking assertion failure
CONFIG_DEBUG_ATA=0#Enable debugging ATA driver
CONFIG_SELECT_AES_GLADMAN=0#Select Dr. Gladmans AES assembler code
CONFIG_CARDSTATUS=0#Panic if an IC card is ejected (IDMAN)
CONFIG_IDMAN=0#IDMAN (CRYPTO must be enabled)
CONFIG_NET_DRIVER=0#Enable NIC drivers
CONFIG_NET_PRO100=0#Intel PRO/100 driver
CONFIG_NET_PRO1000=0#Intel PRO/1000 driver
CONFIG_NET_RTL8169=0#Realtek RTL8169 driver
CONFIG_NET_RE=0#Realtek Family driver
CONFIG_NET_BNX=0#Broadcom NetXtreme GbE driver
CONFIG_NET_AQ=0#Aquantia ACQ107 driver
CONFIG_NET_VIRTIO_NET=0#Enable virtio-net for PRO1000/BNX
CONFIG_NET_V_VIRTIO_NET=0#Enable virtio-net virtual driver
CONFIG_VPN_VE=0#Enable ve (Virtual Ethernet) driver
CONFIG_VTD_TRANS=0#Enable VT-d translation
CONFIG_STORAGE_PD=0#Storage encrypting in protection domain
CONFIG_IDMAN_PD=0#IDMan in protection domain
CONFIG_VPN_PD=0#VPN in protection domain
CONFIG_DISABLE_TCG_BIOS=0#Disable TCG BIOS (TPM related)
CONFIG_ACPI_TIME_SOURCE=1#Use ACPI PM Timer as time source
CONFIG_TCG_BIOS=1#TCG BIOS support
CONFIG_BACKTRACE=0#Enable backtrace in panic
CONFIG_VGA_INTEL_DRIVER=0#Enable vga_intel driver
CONFIG_TTY_VGA=0#VMM output using VGA driver
CONFIG_SHIFT_KEY_DEBUG=0#Debug shell with shift key while booting
CONFIG_DUMP_PCI_DEV_LIST=0#Dump list of PCI devices
CONFIG_IP=0#Enable TCP/IP stack
CONFIG_PCI_MONITOR=1#PCI I/O monitor driver
CONFIG_THREAD_1CPU=0#Disable parallel thread processing
CONFIG_ACPI_IGNORE_ERROR=0#Ignore ACPI DSDT/SSDT parse errors
CONFIG_MAP_UEFI_MMIO=0#Map EfiMemoryMappedIO space
CONFIG_DISABLE_VTD=1#Disable VT-d translation if enabled
CONFIG_DMAR_PASS_THROUGH=0#Enable DMAR pass-through
CONFIG_USE_SYSCALL64=0#Use SYSCALL for 64bit system call
CONFIG_SQLITE=0#SQLite in protection domain
```