本文主要记录一类常见自托管场景:Unraid 宿主机使用 Intel UHD 770 核显,通过 SR-IOV 创建 VF,把 VF 直通给 Ubuntu 虚拟机,用于 VAAPI / QSV / FFmpeg 以及 Jellyfin / Plex 等媒体服务的硬件转码。命令与 PCI 地址以示例给出,部署时请按本机 lspci 结果替换。
需要注意的是:SR-IOV VF 更适合计算与转码,通常不适合当作物理 HDMI / DP 桌面输出。虚拟机主显示仍应保留 VNC / Virtio / QXL;核显 VF 只当渲染设备。
背景与适用范围
Unraid 宿主机
└── 00:02.0 = Intel UHD 770 PF(留给宿主机 i915)
├── 00:02.1 = VF → 可直通 VM 1
├── 00:02.2 = VF → 可直通 VM 2
└── 00:02.x = 其他 VF
适用:
- 宿主机是 Unraid,核显为 UHD 770(常见 PCI ID
8086:4680,以本机为准)。 - 客机为较新的 Ubuntu(文中以 26.04 系内核为例),目标是转码,不是 passthrough 整卡做桌面。
- 客机内最终需要稳定出现
/dev/dri/renderD128(编号以实际为准)。
不适用:
- 希望虚拟机直接驱动主板 HDMI / DP 输出画面。
- 把 PF(
00:02.0)整卡直通给虚拟机,导致宿主机失去 iGPU 管理。
宿主机检查
识别核显与 VF
lspci -nnk | grep -A5 -Ei 'VGA|Display|Intel|4680'
成功创建 VF 后,常见形态是:
00:02.0 ... UHD Graphics 770 ... Kernel driver in use: i915
00:02.1 ... 同上 ... Kernel driver in use: vfio-pci
00:02.2 ... 同上 ... Kernel driver in use: vfio-pci
查看 VF 容量:
cat /sys/bus/pci/devices/0000:00:02.0/sriov_totalvfs
cat /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs
若 sriov_totalvfs 不存在或为 0,写入 sriov_numvfs 失败,说明宿主机侧 i915 SR-IOV 链路尚未就绪。
配置要点
Unraid 上常见做法是使用 i915 SR-IOV 相关插件,安装带 SR-IOV 支持的 i915,并在启动时加载类似参数:
modprobe i915 enable_guc=3 max_vfs=7
实际创建几个 VF 由插件/配置决定。创建后确认:
lsmod | grep '^i915'
dmesg | grep -iE 'i915|guc|sriov|vf'
lspci -nnk -s 00:02.1
VF 理想状态是 Kernel driver in use: vfio-pci。若仍被 i915 占用,需要在 System Devices / VFIO 配置中勾选对应 VF,或走插件的绑定流程。
虚拟机配置
推荐:
| 项 | 建议 |
|---|---|
| Machine | Q35 |
| BIOS | OVMF |
| Primary Display | VNC / Virtio / QXL(保留) |
| GPU | 添加 VF(如 00:02.1),不要选 PF 00:02.0 |
| ROM BIOS | 留空 |
| 音频 | 不必绑 iGPU 音频 |
hostdev 片段示意(function 对应 VF):
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</source>
</hostdev>
原则:一个 VF 只分配给一个 VM;转码设备与主显示分离。
客机:驱动与 grub
确认看到设备
lspci -nnk | grep -A6 -Ei 'VGA|Display|Intel|4680'
关注 Kernel driver in use:期望 i915。若是 xe 或未绑定,继续安装 SR-IOV 友好的 i915 与 blacklist。
安装 i915 SR-IOV DKMS(示例)
较新 Ubuntu 内核上,社区常见方案是 strongtz/i915-sriov-dkms(版本需匹配内核,以下版本号请按 release 页替换):
sudo apt update
sudo apt install -y build-essential dkms "linux-headers-$(uname -r)" wget curl pciutils
I915_SRIOV_VERSION="<version>"
wget -O "/tmp/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb" \
"https://github.com/strongtz/i915-sriov-dkms/releases/download/${I915_SRIOV_VERSION}/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb"
sudo dpkg -i "/tmp/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb"
dkms status | grep -i i915
若 DKMS 构建失败,先核对 uname -r 与 linux-headers 是否匹配、/lib/modules/$(uname -r)/build 是否存在。
Secure Boot:第三方 DKMS 在开启 Secure Boot 时可能无法加载。转码 VM 最简单的做法是关闭 Secure Boot;若必须开启,需要模块签名与 MOK,复杂度明显上升。
grub 参数
在 /etc/default/grub 的 GRUB_CMDLINE_LINUX_DEFAULT 中追加:
i915.enable_guc=3 module_blacklist=xe
sudo update-grub
sudo update-initramfs -u
sudo reboot
含义:
i915.enable_guc=3:启用 GuC / HuC 相关能力,SR-IOV 场景通常需要。module_blacklist=xe:避免xe抢占 Intel 核显 VF。
客机验证
PCI 与 DRI
lspci -nnk | grep -A6 -Ei 'VGA|Display|Intel|4680'
ls -l /dev/dri
dmesg | grep -iE 'i915|guc|huc|drm'
理想情况:
Kernel driver in use: i915(Kernel modules里出现xe可以接受)。- 存在
card0与renderD128(编号以本机为准)。 - dmesg 无 firmware / GuC 初始化失败。
转码主要使用 render 节点,例如 /dev/dri/renderD128。
VAAPI 用户态
sudo apt update
sudo apt install -y vainfo intel-gpu-tools ffmpeg intel-media-va-driver-non-free
无桌面服务器不要裸跑 vainfo 依赖 X,应指定 DRM 设备:
vainfo --display drm --device /dev/dri/renderD128
正常时应能看到 Intel iHD 驱动与 H.264 / HEVC / VP9 等 profile 及 decode / encode 入口。若提示 can't connect to X server,在服务器上通常不是 VAAPI 不可用,改用上面的 DRM 方式即可。
FFmpeg 冒烟
VAAPI H.264:
ffmpeg -hide_banner \
-init_hw_device vaapi=va:/dev/dri/renderD128 \
-filter_hw_device va \
-f lavfi -i testsrc2=size=1920x1080:rate=30 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi \
-frames:v 120 \
-f null -
HEVC 将 -c:v 换成 hevc_vaapi 再测。QSV 示意:
ffmpeg -hide_banner \
-init_hw_device qsv=hw:/dev/dri/renderD128 \
-f lavfi -i testsrc2=size=1920x1080:rate=30 \
-c:v h264_qsv \
-frames:v 120 \
-f null -
另开终端观察:
sudo intel_gpu_top
# 部分环境可试
sudo intel_gpu_top -d sriov
编码时应看到 Video / Render 类指标变化。VAAPI 成功而 QSV 失败时,优先以 VAAPI 作为生产转码路径;QSV 对 FFmpeg、oneVPL / MediaSDK 与设备枚举更敏感。
Docker 媒体服务映射
客机跑容器时需把 DRI 映射进去:
ls -l /dev/dri
getent group render
getent group video
Compose 示意:
services:
jellyfin:
image: jellyfin/jellyfin:latest
restart: unless-stopped
devices:
- /dev/dri:/dev/dri
group_add:
- "render"
- "video"
volumes:
- ./config:/config
- ./cache:/cache
- /path/to/media:/media
ports:
- "8096:8096"
服务内硬件加速优先选 VAAPI 或 Intel QuickSync,设备指向 /dev/dri/renderD128。权限不对时可先只映射 renderD128 做对照。
常见问题
| 现象 | 优先检查 |
|---|---|
无 /dev/dri | VF 是否直通;DKMS 是否成功;是否被 xe 抢占;Secure Boot;内核与 DKMS 是否匹配 |
Kernel driver in use: xe | grub 是否含 module_blacklist=xe,更新 grub/initramfs 后重启 |
vainfo 报 X server | 用 --display drm --device /dev/dri/renderD128 |
| VAAPI 通、QSV 不通 | 生产可只用 VAAPI |
| 想 HDMI 出画面 | SR-IOV VF 通常不适合;改评估整卡直通或其他方案 |
注意事项
- 不要直通 PF。宿主机需要保留
00:02.0上的 i915 管理面。 - PCI 地址、设备 ID、render 节点号因主板与内核而异,一律以本机
lspci/ls /dev/dri为准。 - DKMS 版本与内核绑定;升级内核后要复查
dkms status与转码冒烟。 - 文档中的版本号、插件名会随社区更新变化,以当前 release 与 Unraid 插件页为准。
- 生产变更前确认影响范围:改 grub、绑 VF、重启 VM 会中断正在进行的转码会话。
相关阅读
同系列还可对照:
- 媒体库播放排障:从会话创建到 HLS / DirectPlay / 字幕链路:服务端硬解回退与 VAAPI 日志口径。
- 媒体库探测选型:MediaInfo 与 ffprobe 该怎么分工:扫描探测与播放事实分层,和硬解能力矩阵分开看。
来源
本文改写自 Octans 项目 usage 层 Unraid UHD 770 SR-IOV + Ubuntu 转码教程。路径与版本已做通用化;具体内核 / DKMS 组合以目标环境验证为准。