本教程在ubuntu下实现。具体实现参考了ledisbest[^1]的教程。

配置一个可用的虚拟机

CPU开启iommu

需要在bios里开启虚拟化技术

不同牌子的设置不同的

/etc/default/grub

1
2
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet amd_iommu=on iommu=pt"
(amd_iommu/intel_iommu/AuthenticAMD)

更新引导

1
2
3
4
sudo update-grub

# 并查看是否启动成功
dmesg | grep -E "DMAR|IOMMU"

查看iommu组是否有效

使用LEDs-single-gpu-passthrough/ resources / iommuamd.sh脚本查看,需要保证显卡的所有项在一个组下

1
2
3
4
5
IOMMU group 16
0a:00.0 VGA compatible controller \[0300\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin \[Radeon RX 550 640SP / RX 560/560X\] \[1002:67ff\] (rev cf)
Driver: amdgpu
0a:00.1 Audio device \[0403\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin HDMI/DP Audio \[Radeon RX 550 640SP / RX 560/560X\] \[1002:aae0\]
Driver: snd\_hda\_intel

上图是amd显卡的结果,3090也只有这两项

💡 这个信息需要保存一下很重要,之后将会用到

VFIO模块设置

/etc/modprobe.d/vfio.conf

在vfio.conf里面添加

1
2
3
options vfio-pci ids=1002:67ff,1002:aae0 # ids需要修改,使用,进行分割
options vfio-pci disable_idle_d3=1
options vfio-pci disable_vga=1

这里的ids来自于iommu组里的信息。都需要添加到这里。

软件安装

1
2
3
4
sudo apt install qemu-kvm
sudo apt install virt-manager
sudo apt install libvirt-bin
sudo apt insatll bridge-utils

开启服务

1
2
3
4
5
6
sudo systemctl start libvirtd
sudo systemctl start virtlogd.socket

# 启用虚拟网络
sudo virsh net-start default
sudo virsh net-autostart default

配置

  1. 下载windows镜像
  2. 下载https://github.com/virtio-win/virtio-win-pkg-scripts 提升虚拟机性能。

管理

为方便管理,需要建立2个文件夹:VM(存镜像),storage(存内容)。

安装

本地安装介质,游览选择VM中的windows镜像来进行安装
image.png
下方无法检测到的时候,需要自己手动添加MW10内容。然后选择左下角创建存储池,选择到之前创建的storage位置。
image.png
上面只是位置的映射,下面才是创建池,添加卷并分配空间。
image.png
image.png
依旧叫win10,方便后续操作。

重要

一定要选在安装前自定义配置,选中。
image.png

配置驱动

这里是edk2-ovmf,这个是arch的,在ubuntu下叫OVMF,反正后缀是一致的。
image.png

硬盘

image.png

添加virtio的驱动

就是之前下载的另一个vm文件
image.png
需要在引导里添加2个cdrom设备
image.png

开始安装

引导

直接按任意键进行就可以进入安装界面。
image.png
输入exit, 选择boot manager,一般选择第一个dvd

安装

需要加载virtio的硬盘

image.png
之后选择加载驱动程序,并游览选择
image.png
选择对应的win10。这里还需要添加virtio的网卡驱动
image.png
同理,选择win10,amd64

以上操作完成之后就可以直接点击安装,这里不需要管磁盘的问题。

配置防virt休眠

因为要单卡直通,通完如果宿主机休眠了,这个虚拟机会裂开的。

创建hooks

1
sudo mkdir /etc/libvirt/hooks

LEDs-single-gpu-passthrough中也就是hooks里的3个文件放到创建的hooks文件夹里面。并都变成可执行的文件:

1
sudo chmod +x /etc/libvirt/hooks/*

把两个脚本软链接到根目录的bin文件夹(这里的2个文件其实就是负责显卡的直通和释放的)

1
2
sudo ln -s /etc/libvirt/hooks/vfio-startup.sh /bin/vfio-startup.sh
sudo ln -s /etc/libvirt/hooks/vfio-teardown.sh /bin/vfio-teardown.sh

防止休眠

1
sudo vim /etc/systemd/system/libvirt-nosleep@.service

在libvirt-nosleep@.service里面添加:

1
2
3
4
5
[Unit]
Description=Preventing sleep while libvirt domain "%i" is running
[Service]
Type=simple
ExecStart=/usr/bin/systemd-inhibit --what=sleep --why="Libvirt domain \"%i\" is running" --who=%U --mode=block sleep infinity

更改权限:

1
sudo chmod 644 -R /etc/systemd/system/libvirt-nosleep@.service

变成系统文件

1
sudo chown root:root /etc/systemd/system/libvirt-nosleep@.service

配置Libvirt

编辑libvirt.conf

1
2
3
4
5
6
7
8
9
sudo vim /etc/libvirt/libvirtd.conf

# 找到这两行,把前面的#删掉:
unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"

# 可以选择把这两行添加到文件的最后面(日志文件),方便后续排错:
log_filters="1:qemu"
log_outputs="1:file:/var/log/libvirt/libvirtd.log"

image.png
image.png

编辑qemu.conf

1
sudo vim /etc/libvirt/qemu.conf

把#user = “root”改成user = “zcdu”,#group = “root”改成group = “libvirt”
image.png
把自己添加到libvirt组里面

1
sudo usermod -a -G libvirt 用户名

重启电脑或者重启libvirt

1
2
sudo systemctl restart libvirtd.service
sudo systemctl restart virtlogd.socket

导出显卡bios

最简单使用gpu-z来导出显卡的rom配置文件。这是一个16进制文件,然后使用bless来编辑,还是智能bless,其他都不好用。

配置

nvidia需要,amd是不需要的。amd yes!!

查找字符”VIDEO”

image.png
把VIDEO前面第一个大写U.(十六进制是55)之前的所有的headers都删掉.
image.png
没删错的话,前面的几位是一致的。

Ubuntu/OpenSUSE/Mint(用AppArmour的发行版)可以保存到/usr/share/vgabios里面。但是后面是选择位置的,所以也没必要强求。

修改权限

1
sudo chmod -R 660 vbios.rom

更改拥有者

1
sudo chown zcdu(你的用户名):users vbios文件.rom

添加显卡到虚拟机

添加设备

image.png

需要把之前iommu里的所有项都添加进来

启用XML编辑, 在显卡的所有pci设备里面

image.png
在之后添加:

1
<rom bar="on" file="/path/to/patched.rom"/> # 需要把rom的绝对路径写进来

image.png

删除

把信道,usb转接,显卡qxl,触摸板那些东西删掉。串口(删除显示s啥的协议才能删除qxl)

显卡qxl必须删掉!

添加io设备

添加你的USB设备,比如鼠标、键盘和USB耳机。

修改cpu配置为直通

image.png

绕过英伟达Geforce显卡防虚拟化检测

编辑XML:
在之前添加(value应该等于8-12个字母):AMD显卡可以用”AuthenticAMD”作为id但不需要,因为AMD不会拦着你显卡虚拟化。

1
<vendor_id state='on' value='randomid'/>

之间添加:

1
2
3
<kvm>
<hidden state='on'/>
</kvm> # 直接在hyperv之后添加就行

image.png

之后就可以快乐的玩耍了!!!

文件的交互

使用ndb来挂载qcow2.

前置

1
sudo apt install qemu-nbd

挂载

1
2
3
4
5
sudo qemu-nbd -c /dev/nbd0 /qcow2文件

# 可以使用lsblk查看所有盘

# sudo mount /dev/nbd文件盘 /mnt

重新构建镜像

删除防libvirt休眠的配置。
删除/bin中的vfio-startup.sh和vfio-teardown.sh

问题

无法进入虚拟机

可能一

多删除了一个usb接口,这个hub应该是我的绿联的hub,需要加进来才能有鼠标和键盘。这是会导致问题的
image.png

参考

[^1 ] https://www.bilibili.com/video/BV1KK4y1S7p2?spm_id_from=333.999.0.0