相信大家在使用linux时, 时常因为不能运行windows应用感到困扰(例如各种游戏). 尽管已经有wine、proton等兼容工具来解决这个问题, 但是仍然有可能遇到问题. 而在各种解决方案中, 在虚拟机中运行windows应用显然是兼容性最好的一种方案. 为了在虚拟机中得到优秀的图形性能, 可以选择将宿主机的GPU直通到虚拟机中.
自检
在开始阅读前, 请先检查自己的硬件能不能支持显卡直通.
首先查看BIOS中有没有硬件虚拟化(Intel:VT-D, AMD:AMD-Vi)及iommu的开关, 如果没有启用的话先启用.
-
CPU支持硬件虚拟化, 可以在厂商官网看参数.
-
你除了要直通的显卡之外还有别的GPU(集成的也可以).
-
支持iommu, 且分组正确:在内核启动参数中(这个不用教了吧, 不同bootloader方法不一, 也可以直接写进cmdline里, 请自行搜索方法)写入
intel_iommu=on
(AMD则是amd_iommu=on
). 重启后, 执行sudo dmesg | grep 'IOMMU enabled'
, 如果有输出, 则说明支持iommu.检查分组, 以下命令可以直接一行复制进终端运行
for d in /sys/kernel/iommu_groups/*/devices/*; do n=${d#*/iommu_groups/*}; n=${n%%/*}; printf 'IOMMU Group %s ' "$n"; lspci -nns "${d##*/}"; done;
在输出中, 如果你的独显所在的分组只有你要直通的显卡(加上附属的音频设备), 像下面这样, 就说明ok.
... IOMMU Group 14 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104M [GeForce RTX 3070 Mobile / Max-Q] [10de:249d] (rev a1) IOMMU Group 14 01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1) ...
如果所在组里有一对设备的话, 你只能去研究其他奇技淫巧了.
如果你的系统顺利通过了以上测试, 那么恭喜你, 你大概率可以成功.
隔离独显
为了把独显通到虚拟机里, 显然需要把显卡从宿主上隔离. 把显卡绑到vfio-pci上.
新建文件 /etc/modprobe.d/vfio.conf
, 写入
options vfio-pci ids=10de:249d,10de:228b
将 10de:249d,10de:228b
替换为检查分组的输出中中括号内形如xxxx:xxxx
内的ID, 用逗号隔开.
在这之后, 要让vfio-pci在系统启动过程中提前加载, 以防显卡驱动在她之前就把显卡给绑定了. 这一步对于不同initramfs生成工具会有些许不同, 本文给出mkinitcpio和dracut的步骤. 如果你用的是booster等其他工具, 可以自己查找提前加载内核模块的教程, 总体来说大同小异.
mkinitcpio
编辑 /etc/mkinitcpio.conf
, 加入下列模块.
MODULES=(... vfio_pci vfio vfio_iommu_type1 ...)
注意:如果你提前加载了显卡驱动, 这些加上的模块所有都必须写在显卡驱动之前.
重新生成initramfs
sudo mkinitcpio -P
dracut
新建文件 /etc/dracut.conf. d/10-vfio.conf
, 写入
force_drivers+=" vfio_pci vfio vfio_iommu_type1 "
重新生成initramfs
sudo dracut --regenerate-all --force
设置完毕后, 重启系统, 如果你在fastfetch或者neofetch里看不到刚刚操作了的显卡, 那就说明成功了. 更严谨的检查方式是在终端中执行
lspci -nnk -d 10de:249d #10de:249d替换成前面得到的形如xxxx:xxxx的id
如果输出中有这么一行
Kernel driver in use: vfio-pci
就说明成功了.
创建虚拟机
作者用的是virt-manager (vmm) + qemu/kvm, 理论上所有libvirt的前端都适配本教程, 不过既然vmm是free software, 又相当好用, 所以我很推荐你去下一个. 在arch下安装这些东西只需这些包:qemu-full virt-manager dnsmasq
和aur包 virt-bootstrap-git
. 别的发行版请自己安装对应的包, 相信对各位大神来说这是轻而易举的. 安装之后, 可以下载 win10的iso.
用vmm创建虚拟机跟着引导走就行了, 非常简单. 中间有很多可能出现的坑, 如果你真的遇到了请自行运用搜索引擎解决.
虚拟机网络的各种疑难杂症也是非常之多, 之后可能会出一篇专题讲.
中间遇到问题推荐看archwiki的libvirt和virt-manager. 告诉读者们一个我踩过的坑:一定要启用ip转发, 如果进行了各种设置都没用, 一定要检查是不是自己的代理软件在作祟.
创建虚拟机后, 在vmm中给你的虚拟机添加硬件, 在PCI设备中找到你的显卡(及其音频设备)然后添加到虚拟机中.
确保虚拟机网络可用后, 在虚拟机中下载并安装spice-guest-tools和独显驱动(你直通到虚拟机的显卡的驱动).
安装IddSampleDriver
如果你用的是外接显示器的话, 把外接显示器连到独显上其实就可以直接用了. 如果有HDMI欺骗器的话, 可以跳过这一部分, 直接插上就好了. 如果你什么都没有, 那么你就必须要装IddSampleDriver了. 其实我很推荐你去搞一个HDMI欺骗器(如果你的电脑有接口的话), 十块钱不到就能买到. IddSampleDriver其实会有一定的性能问题.
IddSampleDriver可以为你的windows系统添加虚拟显示器(简单理解为hdmi欺骗器集成到了系统中). 到时候你的显卡会输出到这个虚拟显示器中, 而你将通过looking-glass看到这个虚拟显示器的画面.
以下命令请在虚拟机中有管理权限的powershell对话中运行(ctrl+x打开的菜单里有).
安装scoop
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get. scoop. sh | Invoke-Expression
添加bucket
scoop bucket add extras
scoop bucket add nonportable
安装IddSampleDriver
scoop install iddsampledriver-ge9-np -g
之后, 你应该就能在显示设置里看到多了个显示器, 把她设置成你想要的分辨率.
在宿主机上安装looking-glass客户端
Arch用户可以安装aur包 looking-glass
.
其他发行版可以自己编译安装.
常用发行版的编译依赖如下:
debian (ubuntu)
sudo apt install cmake gcc g++ libegl-dev libgl-dev libgles-dev libfontconfig-dev libgmp-dev libspice-protocol-dev make nettle-dev pkg-config binutils-dev libx11-dev libxfixes-dev libxi-dev libxinerama-dev libxss-dev libxcursor-dev libxpresent-dev libxkbcommon-dev libwayland-bin libwayland-dev wayland-protocols libpipewire-0. 3-dev libsamplerate0-dev libpulse-dev fonts-dejavu-core
fedora
sudo dnf install cmake gcc gcc-c++ libglvnd-devel fontconfig-devel spice-protocol make nettle-devel pkgconf-pkg-config binutils-devel libXi-devel libXinerama-devel libXcursor-devel libXpresent-devel libxkbcommon-x11-devel wayland-devel wayland-protocols-devel libXScrnSaver-devel libXrandr-devel dejavu-sans-mono-fonts
其他发行版可前往[官方文档](https://looking-glass. io/wiki/Installation_on_other_distributions)中查找.
复制仓库并编译:
git clone --recursive https://github. com/gnif/LookingGlass. git
cd LookingGlass
mkdir client/build
cd client/build
cmake . . /
make
sudo make install
运行 looking-glass-client
, 如果有输出则安装成功.
在虚拟机中安装并配置looking-glass
添加共享内存设备
编辑虚拟机xml文件. vmm可以在概况/overview看到整个虚拟机的xml配置, 你也可以选择像下面这样用virsh打开配置文件.
sudo virsh list --all #列出所有虚拟机名称
sudo EDITOR=vim virsh edit win11 #win11替换成你的windows虚拟机的名称, vim可以换成你喜欢的编辑器
添加下面几行:
<shmem name='looking-glass'>
<model type='ivshmem-plain'/>
<size unit='M'>64</size>
</shmem>
其中64是内存大小(单位为mb), 取决于你显示器的规格, 用以下公式得出:
$$
高 \times 宽 \times 4 \times 2 \div 1024 \div 1024+10
$$
得到的结果向上取到最近的 $2^n$ .
其中的4如果要启用HDR的话应该替换成8(就算你在windows里启用了, 你在宿主机里也显示不出来, 不推荐).
例如说, 对于我的显示器
$$
2560\times1600\times4\times2=32768000\
32768000\div1024\div1024+10=41. 25
$$
$41. 25$ 向上取到最近的 $2^n$ 是$64$. 因此我的配置中内存大小便是64.
常见分辨率 (sdr) 的内存大小请参考下面的表格.
分辨率 | 内存大小 |
---|---|
1920x1080 (1080p) | 32 |
1920x1200 (1200p) | 32 |
1920x1440 (1440p) | 32 |
3840x2160 (2160p/4K) | 128 |
设置权限
创建文件 /etc/tmpfiles.d/10-looking-glass.conf
, 写入下面的内容.
f /dev/shm/looking-glass 0660 user kvm -
其中user换成你的用户名.
重启之后权限设置应该就正确了.
确保输入输出正常
在虚拟机中从这里找到最新版本virtio-win的文件夹, 下载里面的exe文件并安装.
之后, 确保你的虚拟机里有一个信道spice (spice channel) 和显示spice,而且开启了监听.
如果有的话, 移除掉虚拟机任何tablet (平板之类的) 设备.
使用
到这里, 差不多就可以使用looking-glass来访问虚拟机了. 运行
looking-glass-client -F #-F: 全屏
即可. 关于快捷键以及参数配置可以在官方文档中查询, 停止输入到虚拟机中默认的快捷键是 Scrlk+I
.
如果可以正常使用的话, 通过vmm进入到虚拟机中, 将主显示器设置为独显连接的显示器, 然后将虚拟机的视频设备设置为None/无. 重启, 你会发现vmm里啥都看不见, 那么就说明你大功告成了, 通过looing-glass即可正常访问.
最后, 为了避免性能问题, 编辑虚拟机的xml文件, 找到memballoon相关的几行, 全部删除掉, 换成下面这行:
<memballoon model="none"/>
玩你的游戏去吧.
标签:vfio,VFIO,虚拟机,KVM,dev,devel,glass,显卡 From: https://www.cnblogs.com/reflectionblue/p/18290605