FreeBSD13 を Hyper-V 環境にインストールしてみた所感

# はじめに

ＦｒｅｅＢＳＤ１３（`FreeBSD 13.0`）をＷｉｎｄｏｗｓ１０（`Windows 10 Pro 20H2`）で稼動するＨｙｐｅｒ－Ｖ環境でインストールしてみた。

[ＦｒｅｅＢＳＤのインストールに関する諸々](https://wiki.ninth-nine.com/FreeBSD/FreeBSD13-install)についてはそちらを見てもらうものとして、また[Ｈｙｐｅｒ－Ｖのセットアップに関する諸々](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)についても完了しているものとする。

また特にセットアップの仕方と行った部分については省略する。今回は物理環境や他の仮想環境とは違う点に絞ってまとめてみた。

今回目的や永続性は考慮せずに設定してるので、かなりの部分が「てきとー」である。用途に応じてリソースを割り当てて欲しい。

## 前提条件
- ＦｒｅｅＢＳＤ１３（`FreeBSD 13.0`）のＩＳＯイメージからのインストール
- Ｗｉｎｄｏｗｓ１０（`Windows 10 Pro 20H2`）のＨｙｐｅｒ－Ｖ
- 仮想マシン作成時にＦｒｅｅＢＳＤの対応デバイスに合わせた設定
    - 仮想マシン世代：第二世代（ＵＥＦＩ環境・６４ビットＯＳのみ対応）
    - メモリ： てきとーに割り当ててみる＆動的メモリの使用を許可
    - ネットワーク構成： `Default Switch` に接続
    - ハードディスク： 仮想ハードディスクを作成するでてきとーに割り当ててみる
    - インストールオプション： ブートＣＤ／ＤＶＤからＯＳをインストールで、インストールＩＳＯイメージファイルを指定する
- 作成された仮想マシンに対する追加の設定
    - セキュリティ： セキュアブートを「無効に」する
    - プロセッサ： 仮想プロセッサの数をてきとーに変更する
    - 自動起動・自動停止： 用途に応じて設定
- 作成された仮想マシンに対する追加の設定 :new: ※ＣＵＩ設定・確認が必要
    - シリアルコンソール： 名前付きパイプの設定

# Ｈｙｐｅｒ－ＶとＦｒｅｅＢＳＤの仕様のマッチング

## ＣＭＯＳクロックタイム（ＢＩＯＳ時間）

ハードウェア上（仮想マシン上）ではＵＴＣとして取り扱われる。カスタム項目も無いことから、ＣＭＯＳクロックタイムはＵＴＣである前提でセットアップすること。

具体的には以下の手順で確認する。

* `/etc/wall_cmos_clock` と言うファイルが「無い」こと。あれば削除する。
* `sysctl machdep.wall_cmos_clock` を実行して、結果の値が「０」であること。「０」以外であれば「０」にすること。

今時のインストーラーは本設定を「行わない」ので、物理環境でもＵＴＣ時間で運用することをオススメする。

## ＰＳ／２レガシーデバイス

第二世代仮想マシン環境ではいわゆるＰＳ／２レガシーデバイスが無い。これは標準キーボードおよび標準マウスのデバイスドライバを使用しなくて良いことを意味する。
むしろ無いのに探そうとするなど、無駄に時間を浪費するため、以下の設定を `/boot/loader.conf` に記述の上、無効化する。

```shell: /boot/loader.conf
hint.atkbdc.0.disabled="1"
hint.atkbd.0.disabled="1"
hint.psm.0.disabled="1"
```

キー入力については `hvkbd0` デバイスによりケアされる。残念なことにマウス（ＨＩＤ）のサポートについて使用することができない。
現時点（２０２３／０４／０１）で１３－ＳＴＡＢＬＥまで降りてきているが、１３．２－ＲＥＬＥＡＳＥには含まれていない(https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=221074 参照)。

自分的には `hvkbd0` が `kbdmux0` に統合されてないのと、`kbd0` が封じ切れてない点が気になる。動いてるので問題無いが…。

```console
 :
WARNING: Device "kbd" is Giant locked and may be deleted before FreeBSD 14.0.
kbd0 at kbdmux0
 :
hvkbd0: <Hyper-V KBD> on vmbus0
 :
```

## ストレージデバイス・ネットワークインターフェース

- ストレージデバイス（ＳＣＳＩコントローラー接続のＨＤＤ）は `daｎ` （ｎ≧０）として参照できる。
- ネットワークインターフェース（ネットワークアダプター接続のＮＩＣ）は `hnｎ` （ｎ≧０）として参照できる。

これについて特記することは無いが、`if_hn(4)` デバイスは見慣れないかもしれないので参考までに。

```console
# ifconfig hn0
hn0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8051b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,TSO4,LRO,LINKSTATE>
        ether 00:15:5d:xx:xx:xx
        inet 172.30.226.166 netmask 0xfffff000 broadcast 172.30.239.255
        media: Ethernet autoselect (10Gbase-T <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
```

また `daｎ` は仮想化ホストバスアダプタ（`hv_storvsc(4)` ドライバ）上にあるため、[ＣＡＭ](https://www.freebsd.org/cgi/man.cgi?cam(4))化されている。

```console
# camcontrol identify da0
camcontrol: ATA ATA_IDENTIFY via pass_16 failed
camcontrol: ATA ATAPI_IDENTIFY via pass_16 failed
# camcontrol tags da0 -v
(pass0:storvsc0:0:0:0): dev_openings  255
(pass0:storvsc0:0:0:0): dev_active    0
(pass0:storvsc0:0:0:0): allocated     0
(pass0:storvsc0:0:0:0): queued        0
(pass0:storvsc0:0:0:0): held          0
(pass0:storvsc0:0:0:0): mintags       2
(pass0:storvsc0:0:0:0): maxtags       255
```

とりあえずタグ付キューイングに対応してるので活用しよう（下記はＺＦＳでの設定例）。

```shell
sysctl vfs.zfs.vdev.async_read_max_active=140
sysctl vfs.zfs.vdev.async_write_max_active=108
```

この辺りのパラメータ調整は、何か負荷のかかる操作中に `gstat` コマンドを実行して、`L(q)` の値（キューイング数）、`r/s` （リードＩＯＰＳ）、`w/s` （ライトＩＯＰＳ）をモニタリングしながら調整する。
この時 `ms/r`（リード当りの処理時間）、`ms/w` （ライト当りの処理時間）とシステム全体の負荷を見ながら当たり障りの無いところで抑えておく。

当たり障りの無いところの見極めは難しいが、ＨＤＤかＳＳＤでも指標が変わってくるので一概には言えない。

## ＴＲＩＭ／ＵＮＭＡＰ対応

Ｈｙｐｅｒ－Ｖの仕様にも書いてあるが、`sysctl kern.geom.disk.daｎ.flags` を実行すると `CANDELETE` の表示があることから、ＴＲＩＭ／ＵＮＭＡＰに対応していることがわかる。その前提でセットアップする。

```console
# sysctl kern.geom.disk.da0.flags
kern.geom.disk.da0.flags: be<OPEN,CANDELETE,CANFLUSHCACHE,UNMAPPEDBIO,DIRECTCOMPLETION,CANZONE>
```

## ＴＰＭ未対応

いわゆるＴＰＭ２．０。残念ながら現時点では未対応である。セキュアブートにも対応してないことからこの当りの機能については触らない方向で。

```
tpmcrb0: <Trusted Platform Module 2.0, CRB mode> iomem 0xfed40000-0xfed40fff on acpi0
device_attach: tpmcrb0 attach returned 6
```

## イベントタイマー

こちらも仮想化イベントドライバが組み込まれているが、ＬＡＰＩＣが選択（`kern.eventtimer.timer`の設定）されている。大した話では無いがこれでいいのかは不明。
よってこれ以上は深掘りしない。

```console
kern.eventtimer.choice: Hyper-V(1000) LAPIC(100) RTC(0)
kern.eventtimer.et.Hyper-V.quality: 1000
kern.eventtimer.et.Hyper-V.frequency: 10000000
kern.eventtimer.et.Hyper-V.flags: 6
kern.eventtimer.et.RTC.quality: 0
kern.eventtimer.et.RTC.frequency: 32768
kern.eventtimer.et.RTC.flags: 17
kern.eventtimer.et.LAPIC.quality: 100
kern.eventtimer.et.LAPIC.frequency: 100000740
kern.eventtimer.et.LAPIC.flags: 15
kern.eventtimer.periodic: 0
kern.eventtimer.timer: LAPIC
kern.eventtimer.idletick: 0
kern.eventtimer.singlemul: 4
```

## タイマーカウンター

```console
kern.timecounter.tsc_shift: 1
kern.timecounter.smp_tsc_adjust: 0
kern.timecounter.smp_tsc: 0
kern.timecounter.invariant_tsc: 0
kern.timecounter.fast_gettime: 1
kern.timecounter.tick: 1
kern.timecounter.choice: ACPI-fast(900) Hyper-V-TSC(3000) TSC-low(-100) Hyper-V(2000) dummy(-1000000)
kern.timecounter.hardware: Hyper-V-TSC
kern.timecounter.alloweddeviation: 5
kern.timecounter.timehands_count: 2
kern.timecounter.stepwarnings: 0
kern.timecounter.tc.ACPI-fast.quality: 900
kern.timecounter.tc.ACPI-fast.frequency: 3579545
kern.timecounter.tc.ACPI-fast.counter: 913986421
kern.timecounter.tc.ACPI-fast.mask: 4294967295
kern.timecounter.tc.Hyper-V-TSC.quality: 3000
kern.timecounter.tc.Hyper-V-TSC.frequency: 10000000
kern.timecounter.tc.Hyper-V-TSC.counter: 1667097865
kern.timecounter.tc.Hyper-V-TSC.mask: 4294967295
kern.timecounter.tc.TSC-low.quality: -100
kern.timecounter.tc.TSC-low.frequency: 1651207337
kern.timecounter.tc.TSC-low.counter: 1948344295
kern.timecounter.tc.TSC-low.mask: 4294967295
kern.timecounter.tc.Hyper-V.quality: 2000
kern.timecounter.tc.Hyper-V.frequency: 10000000
kern.timecounter.tc.Hyper-V.counter: 1667098332
kern.timecounter.tc.Hyper-V.mask: 4294967295
```

タイマーカウンターはむしろＨｙｐｅｒ－Ｖ－ＴＳＣが選択（`kern.timecounter.hardware` の設定）されている。

個人的な感覚で言えば、仮想環境のタイマーの精度はよろしくなく、１／１００秒レベルでジッター（変動）する。常に±３％／秒程度、最大で±１０％／秒くらいの誤差がある。
物理環境での精度だと１／１０００秒レベルで、通常±０．１％／秒未満で最大で±３％／秒くらいの感覚となる。

## ＤｅｆａｕｌｔＳｗｉｔｃｈの扱いについて

仕様によればＮＡＴで閉じた環境ということで、ＤＨＣＰも使用できるという至れり尽くせりな環境。
難しいこと考えなければ、`/etc/rc.conf` には以下の設定を書いて運用しよう。

```shell: /etc/rc.conf
ifconfig_hn0="SYNCDHCP"
```

とりあえずＩＰアドレスの固定方法等については見なかった方向で。
またＨｙｐｅｒ－Ｖが稼動しているマシン（ノートＰＣ上で検証）からＳＳＨコマンドで接続できたことはもちろんのこと、ＰｕＴＴＹといったターミナルソフトでもＦｒｅｅＢＳＤ（ゲストＯＳ）への接続はできた。

ただ内部から外部への接続については問題無いが、外部（ＰＣの外）から内部への通信方法については未検証である。

## ホストの電源状態のモニタリング

ｄｍｅｓｇの精査をした時に気がついたのだが、本体（ホスト）側の電源状態が仮想マシン（ゲスト）から見えていた。
Ａｚｕｒｅ等の仮想化基盤上で運用する場合は無関係だと思うが、ノートＰＣ上で稼動させた場合は、一つ参考になるかもしれない。
これは例えばｔｏｐコマンドを実行するとヘッダー部にその時の充電状態（`battery: 49%`・いたわり充電につき正常な表示）が表示される。
この時、ｔｏｐコマンドは表示桁数の問題から、９１桁以上の端末エミュレータ上で実行される必要がある。

```console
last pid:   898;  load averages:  0.17,  0.13,  0.06; battery: 49% up 0+00:11:54  00:43:03
16 processes:  1 running, 15 sleeping
CPU:  0.0% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 26M Active, 184M Inact, 873M Wired, 2148K Buf, 1981M Free
ARC: 419M Total, 54M MFU, 231M MRU, 4108K Header, 130M Other
     214M Compressed, 332M Uncompressed, 1.55:1 Ratio
Swap: 5120M Total, 5120M Free
```

またｓｙｓｃｔｌコマンドでも電源状態を確認できる。ｓｙｓｃｔｌ名と値と状況は下記のように対応している。

ｓｙｓｃｔｌ名          | １               | ０               | 備考                 |
----------------------- | ---------------- | ---------------- | -------------------- |
`hw.acpi.acline`        | 電源接続         | 電源未接続       | 電源ライン接続状態   |
`hw.acpi.battery.state` | バッテリー放電中 | バッテリー充電中 | バッテリー充放電状態 |

最近のハードウェアの特徴であるが、電源接続中にバッテリー放電している場合もあるので注意が必要である。
またバッテリーモード時であれば `hw.acpi.battery.time` により残り稼動時間（単位・分）も取得できる。

流石にＣＰＵ動作周波数とＣＰＵ温度は取得できていなかった。

### 充電モード

```console
# sysctl hw.acpi.battery
hw.acpi.battery.info_expire: 5
hw.acpi.battery.units: 1
hw.acpi.battery.state: 0
hw.acpi.battery.rate: 0
hw.acpi.battery.time: -1
hw.acpi.battery.life: 49
```

### 放電モード

```console
hw.acpi.battery.info_expire: 5
hw.acpi.battery.units: 1
hw.acpi.battery.state: 1
hw.acpi.battery.rate: 498
hw.acpi.battery.time: 296
hw.acpi.battery.life: 49
```

# シリアルの設定

第二世代ＶＭでは、シリアルの設定・参照は管理コンソール上では行えないので、**管理者権限で立ち上げた**ターミナル（パワーシェル）で実行する。
現在の設定を確認する場合は `Get-VMComPort -VMName "仮想マシン名"` を実行することで状態を確認できる。

```console
PS C:\Users\nork> Get-VMComPort -VMName "FreeBSD 13"

VMName     Name  Path
------     ----  ----
FreeBSD 13 COM 1
FreeBSD 13 COM 2

PS C:\Users\nork> 
```

この時点ではＣＯＭコンソールはどこにも出力されないことがわかる。

設定する場合は適当な名前付きパイプ名を決めて設定を行う。自分は `Hyper-V-仮想マシン名-ComPort-ポート番号` みたいな命名規則とした。これを `Set-VMCOmPort` コマンドを叩いて設定する。

```console
PS C:\Users\nork> Set-VMComPort -VMName "FreeBSD 13" -Number 1 -Path "\\.\pipe\Hyper-V-FreeBSD13-ComPort-1"
PS C:\Users\nork> 
```

再度設定を確認すると、パスが設定されていることがわかる。

```console
PS C:\Users\nork> Get-VMComPort -VMName "FreeBSD 13"

VMName     Name  Path
------     ----  ----
FreeBSD 13 COM 1 \\.\pipe\Hyper-V-FreeBSD13-ComPort-1
FreeBSD 13 COM 2


PS C:\Users\nork> 
```

なお設定された名前付きパイプは、仮想マシン起動中には見えるが、停止すると見えなくなる点に留意しておくこと。

```console
PS C:\Users\nork> Get-ChildItem -Path "\\.\pipe\" -Filter Hyper-V*

    ディレクトリ: \\.\pipe

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
------        1601/01/01      9:00              1 Hyper-V-FreeBSD13-ComPort-1

PS C:\Users\nork>
```

実際にこの名前付きパイプにアクセスする方法だが、あまり良いツールが見つからず、これはこれで課題となる。

# デバイス情報

## dmesg

```console
Copyright (c) 1992-2021 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 13.0-RELEASE-p4 #0: Tue Aug 24 07:33:27 UTC 2021
    root@amd64-builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
SRAT: Ignoring memory at addr 0xc7800000
SRAT: Ignoring memory at addr 0x100000000
SRAT: Ignoring memory at addr 0x1000000000
SRAT: Ignoring memory at addr 0x10000000000
SRAT: Ignoring memory at addr 0x20000000000
SRAT: Ignoring memory at addr 0x40000000000
SRAT: Ignoring memory at addr 0x80000000000
VT(efifb): resolution 1024x768
Hyper-V Version: 10.0.19041 [SP1]
  Features=0x2e7f<VPRUNTIME,TMREFCNT,SYNIC,SYNTM,APIC,HYPERCALL,VPINDEX,REFTSC,IDLE,TMFREQ>
  PM Features=0x0 [C2]
  Features3=0xbed7b2<DEBUG,XMMHC,IDLE,NUMA,TMFREQ,SYNCMC,CRASH,NPIEP>
Timecounter "Hyper-V" frequency 10000000 Hz quality 2000
CPU: 11th Gen Intel(R) Core(TM) i7-11375H @ 3.30GHz (3302.42-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x806c1  Family=0x6  Model=0x8c  Stepping=1
  Features=0x1f83fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,SS,HTT>
  Features2=0xfeda3203<SSE3,PCLMULQDQ,SSSE3,FMA,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND,HV>
  AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM>
  AMD Features2=0x121<LAHF,ABM,Prefetch>
  Structured Extended Features=0xf1bf27a9<FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,NFPUSG,AVX512F,AVX512DQ,RDSEED,ADX,SMAP,AVX512IFMA,CLFLUSHOPT,CLWB,AVX512CD,SHA,AVX512BW,AVX512VL>
  Structured Extended Features2=0x405f42<AVX512VBMI,AVX512VBMI2,GFNI,VAES,VPCLMULQDQ,AVX512VNNI,AVX512BITALG,AVX512VPOPCNTDQ,RDPID>
  Structured Extended Features3=0xbc000010<FSRM,IBPB,STIBP,L1DFL,ARCH_CAP,SSBD>
  XSAVE Features=0xf<XSAVEOPT,XSAVEC,XINUSE,XSAVES>
  IA32_ARCH_CAPS=0x67<RDCL_NO,IBRS_ALL,RSBA,MDS_NO>
Hypervisor: Origin = "Microsoft Hv"
real memory  = 3347054592 (3192 MB)
avail memory = 3204317184 (3055 MB)
Event timer "LAPIC" quality 100
ACPI APIC Table: <VRTUAL MICROSFT>
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 hardware threads
random: registering fast source Intel Secure Key RNG
random: fast provider: "Intel Secure Key RNG"
random: unblocking device.
ioapic0 <Version 1.1> irqs 0-23
Launching APs: 3 1 2
KTLS: Initialized 4 threads
Timecounter "Hyper-V-TSC" frequency 10000000 Hz quality 3000
random: entropy device external interface
[ath_hal] loaded
WARNING: Device "kbd" is Giant locked and may be deleted before FreeBSD 14.0.
kbd0 at kbdmux0
000.000056 [4354] netmap_init               netmap: loaded module
mlx5en: Mellanox Ethernet driver 3.6.0 (December 2020)
nexus0
efirtc0: <EFI Realtime Clock>
efirtc0: registered as a time-of-day clock, resolution 1.000000s
cryptosoft0: <software crypto>
aesni0: <AES-CBC,AES-CCM,AES-GCM,AES-ICM,AES-XTS,SHA1,SHA256>
acpi0: <VRTUAL MICROSFT>
atrtc0: <AT realtime clock> port 0x70-0x71 irq 8 on acpi0
atrtc0: registered as a time-of-day clock, resolution 1.000000s
Event timer "RTC" frequency 32768 Hz quality 0
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <32-bit timer at 3.579545MHz> port 0x408-0x40b on acpi0
cpu0: <ACPI CPU> on acpi0
acpi_syscontainer0: <System Container> on acpi0
vmbus0: <Hyper-V Vmbus> on acpi_syscontainer0
uart0: <16550 or compatible> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
uart1: <16550 or compatible> port 0x2f8-0x2ff irq 3 on acpi0
vmgenc0: <VM Generation Counter> on acpi0
vmbus_res0: <Hyper-V Vmbus Resource> irq 5 on acpi0
battery0: <ACPI Control Method Battery> on acpi0
acpi_acad0: <AC Adapter> on acpi0
Timecounters tick every 10.000 msec
ZFS filesystem version: 5
ZFS storage pool version: features support (5000)
usb_needs_explore_all: no devclass
vmbus0: version 4.0
hvet0: <Hyper-V event timer> on vmbus0
Event timer "Hyper-V" frequency 10000000 Hz quality 1000
hvheartbeat0: <Hyper-V Heartbeat> on vmbus0
hvkvp0: <Hyper-V KVP> on vmbus0
hvshutdown0: <Hyper-V Shutdown> on vmbus0
hvtimesync0: <Hyper-V Timesync> on vmbus0
hvtimesync0: RTT
hvvss0: <Hyper-V VSS> on vmbus0
storvsc0: <Hyper-V SCSI> on vmbus0
hvkbd0: <Hyper-V KBD> on vmbus0
hn0: <Hyper-V Network Interface> on vmbus0
hn0: Ethernet address: 00:15:5d:XX:XX:XX
hn0: link state changed to UP
da0 at storvsc0 bus 0 scbus0 target 0 lun 0
da0: <Msft Virtual Disk 1.0> Fixed Direct Access SPC-3 SCSI device
da0: 300.000MB/s transfers
da0: Command Queueing enabled
da0: 130048MB (266338304 512 byte sectors)
```

## devinfo -rv

```console
nexus0
  efirtc0
  cryptosoft0
  aesni0
  ram0
      I/O memory addresses:
          0x0-0x9efff
          0x100000-0xc6593fff
          0xc6595000-0xc66cbfff
          0xc671f000-0xc779afff
          0xc77ff000-0xc77fffff
  apic0
  acpi0
      Interrupt request lines:
          0x9
    acpi_syscontainer0 pnpinfo _HID=ACPI0004 _UID=0 _CID=none at handle=\_SB_.VMOD
      vmbus0
          I/O memory addresses:
              0xf8000000-0xf87fffff
        hvet0
        unknown pnpinfo classid=f8e65716-3cb3-4a06-9a60-1889c5cccab5 deviceid=99221fa0-24ad-11e2-be98-001aa01bbf6e
        unknown pnpinfo classid=34d14be3-dee4-41c8-9ae7-6b174977c192 deviceid=eb765408-105f-49b6-b4aa-c123b64d17d4
        hvheartbeat0 pnpinfo classid=57164f39-9115-4e78-ab55-382f3bd5422d deviceid=fd149e91-82e0-4a7d-afa6-2a4166cbd7c0
        hvkvp0 pnpinfo classid=a9a0f4e7-5a45-4d96-b827-8a841e8c03e6 deviceid=242ff919-07db-4180-9c2e-b86cb68c8c55
        hvshutdown0 pnpinfo classid=0e0b6031-5213-4934-818b-38d90ced39db deviceid=b6650ff7-33bc-4840-8048-e0676786f393
        hvtimesync0 pnpinfo classid=9527e630-d0ae-497b-adce-e80ab0175caf deviceid=2dd1ce17-079e-403c-b352-a1921ee207ee
        hvvss0 pnpinfo classid=35fa2e29-ea23-4236-96ae-3a6ebacba440 deviceid=2450ee40-33bf-4fbd-892e-9fb06e9214cf
        storvsc0 pnpinfo classid=ba6163d9-04a1-4d29-b605-72e2ffb1dc7f deviceid=140cd59f-fb5d-4dfd-976a-d54ef05992fb
        unknown pnpinfo classid=525074dc-8985-46e2-8057-a307dc18a502 deviceid=1eccfd72-4b41-45ef-b73a-4a6e44c12924
        unknown pnpinfo classid=cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a deviceid=58f75a6d-d949-4320-99e1-a2a2576d581c
        hvkbd0 pnpinfo classid=f912ad6d-2b17-48ea-bd65-f927a61c7684 deviceid=d34b2567-b9b6-42b9-8778-0a4ec0b955bf
        unknown pnpinfo classid=da0a7802-e377-4aac-8e77-0558eb1073f8 deviceid=5620e0c7-8062-4dce-aeb7-520c7ef76171
        unknown pnpinfo classid=3375baf4-9e15-4b30-b765-67acb10d607b deviceid=4487b255-b88c-403f-bb51-d1f69cf17f87
        unknown pnpinfo classid=276aacf4-ac15-426c-98dd-7521ad3f01fe deviceid=f5bee29c-1741-4aad-a4c2-8fdedb46dcc2
        hn0 pnpinfo classid=f8615163-df3e-46c5-913f-f2d2f965ed0e deviceid=5e4f5b37-61e9-4ba5-beff-64dbfdddc551
    unknown pnpinfo _HID=PNP0003 _UID=0 _CID=none at handle=\_SB_.VMOD.APIC
        I/O memory addresses:
            0xfec00000-0xfec00fff
            0xfee00000-0xfee00fff
    vmbus_res0 pnpinfo _HID=VMBUS _UID=0 _CID=none at handle=\_SB_.VMOD.VMBS
    battery0 pnpinfo _HID=PNP0C0A _UID=0 _CID=VIRTUAL BATTERY at handle=\_SB_.VMOD.BAT1
    acpi_acad0 pnpinfo _HID=ACPI0003 _UID=0 _CID=VIRTUAL AC ADAPTER at handle=\_SB_.VMOD.AC1_
    uart0 pnpinfo _HID=PNP0501 _UID=1 _CID=none at handle=\_SB_.UAR1
        Interrupt request lines:
            0x4
        I/O ports:
            0x3f8-0x3ff
    uart1 pnpinfo _HID=PNP0501 _UID=2 _CID=none at handle=\_SB_.UAR2
        Interrupt request lines:
            0x3
        I/O ports:
            0x2f8-0x2ff
    vmgenc0 pnpinfo _HID=HYPER_V_GEN_COUNTER_V1 _UID=0 _CID=VM_GEN_COUNTER at handle=\_SB_.GENC
    atrtc0 pnpinfo _HID=PNP0B00 _UID=0 _CID=none at handle=\_SB_.RTC0
        Interrupt request lines:
            0x8
        I/O ports:
            0x70-0x71
    cpu0 pnpinfo _HID=ACPI0007 _UID=1 _CID=none at handle=\P001
    cpu1 pnpinfo _HID=ACPI0007 _UID=2 _CID=none at handle=\P002
    cpu2 pnpinfo _HID=ACPI0007 _UID=3 _CID=none at handle=\P003
    cpu3 pnpinfo _HID=ACPI0007 _UID=4 _CID=none at handle=\P004
    acpi_timer0 pnpinfo unknown
        I/O ports:
            0x408-0x40b
```

この結果を読むと、準仮想化デバイスは `acpi_syscontainer0` 上の `vmbus0` に置かれている。
またＰＣＩ（ＰＣＩｅ）ブリッジが無いので、`pciconf` コマンドでは何も表示されない。
ＵＡＲＴが存在しているが、これの使いこなしについては調査中。完全ヘッドレスで運用するならＵＡＲＴ使えると便利なんだけど。

# 参考文献

- [Windows にインストールされた Hyper-v の Linux および FreeBSD 仮想マシンがサポートされています。](https://docs.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/supported-linux-and-freebsd-virtual-machines-for-hyper-v-on-windows)
- [HYPER-V でサポートされている FreeBSD 仮想マシン](https://docs.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/supported-freebsd-virtual-machines-on-hyper-v)
- [Hyper-v 上の Linux および FreeBSD 仮想マシンの機能の説明](https://docs.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/feature-descriptions-for-linux-and-freebsd-virtual-machines-on-hyper-v)
- [HYPER-V での FreeBSD の実行に関するベスト プラクティス](https://docs.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/best-practices-for-running-freebsd-on-hyper-v)
- [カーネルデバッグ用の COM ポートの追加](https://learn.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v#add-a-com-port-for-kernel-debugging)
- [Hyper V Gen 2 install has no mouse](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=221074)
- [FreeBSDの時間](https://qiita.com/yamori813/items/d9b0a451f1e115de893f)
- [timecounters(4)](https://www.freebsd.org/cgi/man.cgi?timecounters(4))
- [eventtimers(4)](https://www.freebsd.org/cgi/man.cgi?eventtimers(4))