现在完成了一个 macos+ win10的双系统 vm https://dev.leiyanhui.com/kvm/macos_add_win10/
并且 整理了一个可以基本启动的macos 和 win的脚本 start_bash_macos_win.sh
arch+kvm的安装 看文末链接
usb 和蓝牙的直通
usb直通 是最简单的,所以先处理usb的直通
SPICE 可以把控制机的usb通过网络穿透给受控虚拟机,这个可以看arch的wike 这里主要是宿主机的直通
需要用 lsusb命令
|
|
运行 lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 05ac:821f Apple, Inc. Built-in Bluetooth 2.0+EDR HCI
Bus 001 Device 003: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
Bus 001 Device 002: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
数字分别对应 标识“ host_bus host_addr vendor_id product_id”。
直通蓝牙 和 Mouse 给虚拟机,有两种方式,第一种是 按照设备id 第二种是直接把usb指定的接口直通给虚拟机。 建议用接口方式。这样指定的接口还可以热拔插
例如 usb 鼠标 是hostbus1 hostaddr:002 蓝牙是 hostbus1 hostaddr:006
编辑脚本
|
|
在 -device usb-ehci,id=ehci
后添加行 id=qxhci
这个名字不能有重复的
|
|
这样,无论当前插鼠标的usb接口插入什么设备 都会直通给虚拟机(注意 usb2 和 usb3 对应的host_addr 是不同的,如果分别插入分别获取一次host_addr都直通进去才可以同一个接口 同时支持usb2和usb3)
操作的时候 会有权限问题,可能需要 sudo sh base-win-usb.sh
不是很安全,如果要解决这个问题,可以查看arch关于udev的wiki
鼠标测试成功,用同样的方法添加的时候,我发现ID 05ac:821f Apple, Inc. Built-in Bluetooth 2.0+EDR HCI
这个设备的Device id/host_addr会变化 所以直接用设备的id
添加 port=XXX
参数,鼠标口直接绑定,蓝牙用vendorid 和 productid绑定
|
|
最终完整文件 https://github.com/joyanhui/file.leiyanhui.com/blob/main/pve-unraid-kvm/base-win-usb-bluetooth.sh
因为是已经安装好的 win,所以一直动他主板设备,可能会遇到蓝屏问题。这个是win的问题,不用管他,正常启动过一次 以后不改这些参数 就不会有问题
核显 独显和其他pice设备的直通
启用IOMMU
确认宿主机BIOS里面打开了VT-d/VT-x/VT-i等所有硬件虚拟化支持开关 打开Linux操作系统的iommu开关,在grub启动命令行里面配置,Intel CPU和AMD CPU配置参数有区别:Intel CPU: intel_iommu=on;AMD CPU: amd_iommu=on 重启服务器,检查iommu配置是否生效(dmesg | grep -i iommu,输出“Intel-IOMMU: enabled”表示生效)
sudo nano /etc/default/grub
编辑GRUB_CMDLINE_LINUX_DEFAULT="... intel_iommu=on ..."
另外一个参数 iommu=pt
,这将防止Linux试图接触(touching)无法直通的设备。 不确定是否是必须的
更新一下 grub,
|
|
重启 后检查一下,如果没有下面的分组,信息,那就是 bios的 vt-d 没打开,去打开
cat /etc/default/grub
sudo dmesg | grep -i iommu
[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-linux root=UUID=7ecb4d27-3d12-9d47-ab75-ba39b6fbe737 rw loglevel=3 quiet intel_iommu=on
[ 0.038327] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-linux root=UUID=7ecb4d27-3d12-9d47-ab75-ba39b6fbe737 rw loglevel=3 quiet intel_iommu=on
[ 0.038385] DMAR: IOMMU enabled
[ 0.092270] DMAR-IR: IOAPIC id 2 under DRHD base 0xfed91000 IOMMU 1
[ 0.292307] iommu: Default domain type: Translated
[ 0.292309] iommu: DMA domain TLB invalidation policy: lazy mode
[ 0.320110] DMAR: IOMMU feature fl1gp_support inconsistent
[ 0.320111] DMAR: IOMMU feature pgsel_inv inconsistent
[ 0.320112] DMAR: IOMMU feature nwfs inconsistent
[ 0.320113] DMAR: IOMMU feature pasid inconsistent
[ 0.320114] DMAR: IOMMU feature eafs inconsistent
[ 0.320114] DMAR: IOMMU feature prs inconsistent
[ 0.320115] DMAR: IOMMU feature nest inconsistent
[ 0.320116] DMAR: IOMMU feature mts inconsistent
[ 0.320116] DMAR: IOMMU feature sc_support inconsistent
[ 0.320117] DMAR: IOMMU feature dev_iotlb_support inconsistent
[ 0.320347] pci 0000:00:00.0: Adding to iommu group 0
[ 0.320357] pci 0000:00:02.0: Adding to iommu group 1
[ 0.320367] pci 0000:00:14.0: Adding to iommu group 2
[ 0.320373] pci 0000:00:17.0: Adding to iommu group 3
[ 0.320384] pci 0000:00:1c.0: Adding to iommu group 4
[ 0.320392] pci 0000:00:1c.5: Adding to iommu group 5
[ 0.320400] pci 0000:00:1c.6: Adding to iommu group 6
[ 0.320408] pci 0000:00:1c.7: Adding to iommu group 7
[ 0.320416] pci 0000:00:1d.0: Adding to iommu group 8
[ 0.320431] pci 0000:00:1f.0: Adding to iommu group 9
[ 0.320437] pci 0000:00:1f.2: Adding to iommu group 9
[ 0.320444] pci 0000:00:1f.3: Adding to iommu group 9
[ 0.320451] pci 0000:00:1f.4: Adding to iommu group 9
[ 0.320460] pci 0000:01:00.0: Adding to iommu group 10
[ 0.320468] pci 0000:02:00.0: Adding to iommu group 11
[ 0.320476] pci 0000:05:00.0: Adding to iommu group 12
[ 0.378552] AMD-Vi: AMD IOMMUv2 functionality not available on this system - This is not a bug.
[ 2.573917] pci 0000:00:1f.1: Adding to iommu group 13
[ 2.574294] pci 0000:00:1f.1: Removing from iommu group 13
查看pice情况
sudo nano /mnt/ssd/print_IOMMU.sh
内容
#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done;
sudo sh print_IOMMU.sh
查看所有pice设备
IOMMU Group 0 00:00.0 Host bridge [0600]: Intel Corporation 8th Gen Core Processor Host Bridge/DRAM Registers [8086:3ec4] (rev 07)
IOMMU Group 1 00:02.0 VGA compatible controller [0300]: Intel Corporation CoffeeLake-H GT2 [UHD Graphics 630] [8086:3e9b]
IOMMU Group 10 01:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 0c)
IOMMU Group 11 02:00.0 Network controller [0280]: Broadcom Inc. and subsidiaries BCM43224 802.11a/b/g/n [14e4:4353] (rev 01)
IOMMU Group 12 05:00.0 Non-Volatile memory controller [0108]: KIOXIA Corporation NVMe SSD [1e0f:0009] (rev 01)
IOMMU Group 2 00:14.0 USB controller [0c03]: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller [8086:a12f] (rev 31)
IOMMU Group 3 00:17.0 SATA controller [0106]: Intel Corporation Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode] [8086:a102] (rev 31)
IOMMU Group 4 00:1c.0 PCI bridge [0604]: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #5 [8086:a114] (rev f1)
IOMMU Group 5 00:1c.5 PCI bridge [0604]: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #6 [8086:a115] (rev f1)
IOMMU Group 6 00:1c.6 PCI bridge [0604]: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #7 [8086:a116] (rev f1)
IOMMU Group 7 00:1c.7 PCI bridge [0604]: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #8 [8086:a117] (rev f1)
IOMMU Group 8 00:1d.0 PCI bridge [0604]: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #9 [8086:a118] (rev f1)
IOMMU Group 9 00:1f.0 ISA bridge [0601]: Intel Corporation B150 Chipset LPC/eSPI Controller [8086:a148] (rev 31)
IOMMU Group 9 00:1f.2 Memory controller [0580]: Intel Corporation 100 Series/C230 Series Chipset Family Power Management Controller [8086:a121] (rev 31)
IOMMU Group 9 00:1f.3 Audio device [0403]: Intel Corporation 100 Series/C230 Series Chipset Family HD Audio Controller [8086:a170] (rev 31)
IOMMU Group 9 00:1f.4 SMBus [0c05]: Intel Corporation 100 Series/C230 Series Chipset Family SMBus [8086:a123] (rev 31)
我这里需要直通 核显
[UHD Graphics 630] [8086:3e9b]
wifiBCM43224 802.11a/b/g/n [14e4:4353]
声卡HD Audio Controller [8086:a170]
隔离设备
为了将设备分配给虚拟机,直通的设备和同在一个IOMMU组的所有设备必须将驱动程序更换为 stub 或是 vfio ,以防止宿主机尝试与其交互。对于大多数设备,在虚拟机启动时就可以完成这项工作。 但是核显不行,独显也不行,所以需要隔离掉。
通过设备ID绑定vfio-pci
如果是独显可能需要同时绑定独显上的HDMI声卡和gpu ,但是我没有独显,也没有支持HDMI音频的显示器,所以我这里只绑定核显
[8086:3e9b]
|
|
如果还要直通wifi,声卡不打算直通,改为穿透
|
|
重新生成initramfs sudo mkinitcpio -P
可能还需要 提前加载vfio-pci
因为Arch的linux内核将vfio-pci作为一个模块,我们需要强迫vfio-pci在显卡驱动抢占硬件之前加载。为了达成这一目的,我们向mkinitcpio中添加 vfio_pci, vfio, vfio_iommu_type1, vfio_virqfd: 这步 和 pve的黑名单差不多 意思
mkinitcpio
sudo nano /etc/mkinitcpio.conf
|
|
黑名单
sudo nano /etc/modprobe.d/blacklist.conf
|
|
snd_hda_intel 是声卡,如果不要直通这个地方 不要添加,snd_hda_codec_hdmi是核显的hdmi声卡
booster
sudo nano /etc/booster.yaml
modules_force_load: vfio_pci,vfio,vfio_iommu_type1,vfio_virqfd
dracut
|
|
|
|
防止部分游戏蓝屏,以及macos无限重启
|
|
重新生成initramfs sudo mkinitcpio -P
提示几个 WARNING: Possibly missing firmware for module
不用管他,大致是物理机器缺少驱动的问题
然后重启
重启后检查
重启后屏幕 过了grub后,显示startging versinon XXX.X-X-arch 后 屏幕就不再有输出,有时候 还可能会黑屏或者提示没信号,这是正常的,因为 我们没让arch接触显卡了
重启后重新检查
sudo dmesg | grep -i iommu
应该有 IOMMU enabled
sudo dmesg | grep -i vfio
[ 1.324935] VFIO - User Level meta-driver version: 0.3
[ 1.344914] vfio-pci 0000:00:02.0: vgaarb: deactivate vga console
[ 1.344917] vfio-pci 0000:00:02.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=io+mem
[ 1.345002] vfio_pci: add [8086:3e9b[ffffffff:ffffffff]] class 0x000000/00000000
[ 1.345117] vfio_pci: add [14e4:4353[ffffffff:ffffffff]] class 0x000000/00000000
lspci -k
检查一下 或者 lspci -k | grep -i -e Intel -A 3
lspci -k | grep -i -e Audio -A 3
lspci -nnk -d 8086:3e9b
00:02.0 VGA compatible controller [0300]: Intel Corporation CoffeeLake-H GT2 [UHD Graphics 630] [8086:3e9b]
DeviceName: Onboard IGD
Subsystem: Gigabyte Technology Co., Ltd Device [1458:d000]
Kernel driver in use: vfio-pci
Kernel modules: i915
尝试直通 核显
cd /mnt/ssd/vm-shell/
cp base-win-usb.sh gpu-win-usb.sh && nano gpu-win-usb.sh
添加行-device vfio-pci,host=0000:00:02.0,addr=0x02,x-igd-opregion=on \
屏幕有反应,但是一会还是无信号,不确定是否需要vbios先登录到win,用系统更新自动安装驱动试试看看,驱动装完后 依旧黑屏。
去弄vbois文件,因为我这个uhd630 很常见,有人弄好了,之前在kvm和unraid 都测试过没问题,所以直接拿来用
cd /mnt/ssd/
wget https://file.leiyanhui.com/pve-unraid-kvm/vbios_gvt_uefi.rom
修改上面的参数,同时发现 插槽01 和02 01被VMware显卡用 02被网卡用了 所以把 网卡的改到04 显卡继续用02 02这个位置 就是多数电脑的核显的固定位置
|
|
顺利点亮,qemu有提示 “IGD device 0000:00:02.0 cannot support legacy mode due to existing devices at address 1f.0” 说明是用了UPT 直通模式而不是Legacy
主机类型用pc 也就是 pc-i440fx-7.1 然后vnc那个设置为none 就没有这个提示,可以用Legacy 模式输出 ,但是物理显示屏也是没法显示出来 用户登录之前的画面。
但是我看了qemu的源码 好像 是q35禁用了Legacy 模式
vnc/spice 在登录的时候黑屏,但登录后,两个屏幕都可以显示。 但是因为前面加了鼠标穿透,导致vnc的屏幕鼠标 穿透到物理屏幕导致 vnc屏幕只能观看 无法用控制机的鼠标操作。这个问题后来发现可以通过调整设备的顺序解决 实例代码:查看我的
核显和其他pci直通的另外一个写法
|
|
添加直通wifi
这个很简单,前面vfio之后这里添加一行 就可以了
|
|
声卡直通
声卡和其他一堆设备在一个组里面 还是比较麻烦的。单独记录 查看这里:https://dev.leiyanhui.com/kvm/sound-pass/
直通了 核显 wifi usb 蓝牙 的一个win虚拟机启动脚本
注意 smb功能需要宿主机安装samba sudo pacman -S samba
https://github.com/joyanhui/file.leiyanhui.com/blob/main/pve-unraid-kvm/win-gpu-usb-wifi-bt-vnc-no-sound.md
存在的问题
- vnc显卡的鼠标不可以用,会穿透到物理屏幕。键盘也穿透过去了。因为vnc屏幕定位还是调试用,后期也尝试macos所以 此问题可能以后才会去研究(已经解决看后面的脚本)
- 物理屏幕不会显示kvm的bois引导界面,要等到Windows登录界面之前 才会点亮。
- Q35 机型会提醒IGD核显不能用传统模式 换到pc-i440fx-7.1 模式,vnc 设置none 没有提醒。物理屏依旧不会显示kvm的启动信息,所以没啥区别。
- 声卡直通和映射有坑没解决,没有pve下那么容易,远程用的话 Windows 下 rdp协议可以直接把声音传递到控制机。 macos下还没研究xrdp和其他协议。
另外一个解决了vnc鼠标问题的脚本
macos efi
- 蓝牙可用
- 鼠标键盘 usb 也可以用
- 以太网可用
- smb 到宿主机 可用
- 但是有别的一点问题 需要自定义oc的efi
- spice 声卡不可用
- 没有直通核显
留个坑,慢慢填
本文参考:https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) https://github.com/patmagauran/i915ovmfPkg/issues/8
kvm 进阶和相关小问题处理
查看这里 https://dev.leiyanhui.com/kvm/all_list/
我的kvm脚本参考
https://github.com/joyanhui/file.leiyanhui.com/tree/main/pve-unraid-kvm