跳转到内容

开启 IOMMU:GRUB 与 systemd-boot ​

任何硬件直通都从这一步开始:让内核认得到 IOMMU (输入输出内存管理单元),Intel 平台叫 VT-d,AMD 平台叫 AMD-Vi。没有它,PCI 设备没法被安全地隔离出来交给虚拟机。

为什么需要它 ​

IOMMU 的作用是让直通给虚拟机的设备只能访问自己被分配到的内存,而不是整台宿主机的内存。它是直通能安全工作的硬件前提,也是判断"能不能直通"的第一道门槛。

这一步做完之后,你会得到:内核确认 IOMMU 已启用、vfio 系列模块已加载,为下一篇读懂 IOMMU 分组做好准备。

开始之前 ​

条件怎么确认
CPU 支持虚拟化和 IOMMUIntel 看 VT-x + VT-d,AMD 看 AMD-V + AMD-Vi,查厂商规格页
主板固件里能开启 IOMMU进 BIOS/UEFI 找 "Intel VT-d"、"AMD-Vi" 或直接叫 "IOMMU" 的选项,开启
知道宿主机用哪种引导方式见下文第一步
有物理控制台或带外管理(IPMI/iKVM)见下方警示块

改内核启动参数,配错可能导致宿主机起不来

本文要改的是内核命令行参数,如果文件格式写错(比如 /etc/kernel/cmdline 里出现了多行或空行)或参数本身导致内核崩溃,宿主机可能停在引导阶段无法进入系统。

开始前确认:

  • 你能接触到物理机,或者有 IPMI/iKVM 这类不经过被改动系统就能看到屏幕输出的带外管理方式。只能远程 SSH 管理的机器,风险自负——一旦起不来,SSH 也连不上。
  • 你知道怎么在 GRUB 菜单里临时编辑启动项(开机时按住 Shift 或 Esc 进菜单,选中条目按 e,删掉可疑参数后按 Ctrl+X 临时启动一次,这次修改不会写回磁盘)。这是最快的临时回退手段。
  • 从文件层面回退的方法:把 /etc/default/grub 或 /etc/kernel/cmdline 改回修改前的内容,重新执行下文对应的生效命令(update-grub 或 proxmox-boot-tool refresh),再重启。

操作步骤 ​

1. 确认宿主机用的是哪种引导方式 ​

PVE 用 ZFS 做根分区、或者以 UEFI 模式安装时,通常由 proxmox-boot-tool 管理 systemd-boot;传统 MBR/单块 ext4 安装通常用 GRUB。最可靠的判断方法是看开机画面:蓝色界面是 GRUB,黑底白字的简洁菜单是 systemd-boot。也可以在宿主机 shell 里查看:

sh
# 宿主机 shell
proxmox-boot-tool status

有输出(列出了 ESP 分区)说明这台机器由 proxmox-boot-tool 管理,按下文 systemd-boot 的方法改;命令报错或提示未使用,按 GRUB 的方法改。

2. 编辑内核命令行 ​

两种方式二选一,只改对应你机器的那一种,改错文件不会生效,也不会报错提醒你。

GRUB:

sh
# 宿主机 shell,先备份
cp /etc/default/grub /etc/default/grub.bak

用编辑器打开 /etc/default/grub,找到 GRUB_CMDLINE_LINUX_DEFAULT 这一行,追加参数:

  • Intel 平台:intel_iommu=on
  • AMD 平台:AMD-Vi 默认已开启,通常不需要额外参数

改完执行:

sh
# 宿主机 shell
update-grub

systemd-boot(proxmox-boot-tool 管理):

sh
# 宿主机 shell,先备份
cp /etc/kernel/cmdline /etc/kernel/cmdline.bak

用编辑器打开 /etc/kernel/cmdline,这个文件必须只有一行,把参数追加到已有内容末尾,用空格分隔,不要新起一行。

改完执行:

sh
# 宿主机 shell
proxmox-boot-tool refresh

Intel 较新内核可能已经默认开启

较新的内核(6.8 及以上)在 Intel 平台上默认启用 IOMMU,不加 intel_iommu=on 也可能已经生效。PVE 9.x 的默认内核通常满足这个条件,但不同小版本表现可能不同,加上这个参数更保险,也方便下一步验证。

3. 重启并验证 ​

sh
# 宿主机 shell
reboot

重启后检查内核命令行确实带上了参数:

sh
# 宿主机 shell
cat /proc/cmdline

再检查 IOMMU 是否真的被内核启用:

sh
# 宿主机 shell
dmesg | grep -e DMAR -e IOMMU -e AMD-Vi

看到类似 DMAR: IOMMU enabled 或 AMD-Vi: Interrupt remapping enabled 的行,说明成功。完全没有输出,通常是 BIOS 里没开,或者改错了文件(比如机器实际用 GRUB 却改了 /etc/kernel/cmdline)。

4. 加载 vfio 模块 ​

直通设备需要内核把设备从原驱动接管到 vfio-pci。让相关模块在开机时自动加载:

sh
# 宿主机 shell
cat <<'EOF' > /etc/modules-load.d/vfio.conf
vfio
vfio_iommu_type1
vfio_pci
EOF
update-initramfs -u -k all
reboot

不用再加 vfio_virqfd

老教程里常见的第四个模块 vfio_virqfd 在现在的内核里已经并入 vfio 本身,单独加载会报错或什么都不做,不用管它。

检查结果 ​

sh
# 宿主机 shell
lsmod | grep vfio

应该能看到 vfio、vfio_iommu_type1、vfio_pci 都已加载。结合上一步 dmesg 的输出,两项都确认后再继续下一篇读懂 IOMMU 分组——分组是否干净,决定了具体哪个设备能不能被单独直通。

常见问题 ​

BIOS 里根本找不到 IOMMU/VT-d 选项。 部分消费级主板把这个选项隐藏得很深(可能在 "Advanced" → "CPU Configuration" 或 "North Bridge" 下),也有极少数低端板子确实不支持。先更新到主板厂商最新的 BIOS 版本再找一遍。

参数加了,dmesg 还是没有输出。 大概率是改错了文件——用第 1 步的方法重新确认引导方式;也可能是 BIOS 里的 IOMMU 开关本身没开,或者是老款主板把它和 CSM/Legacy 模式绑在一起,需要先切到纯 UEFI 启动。

改完参数进不了系统了。 按上文的 Shift/Esc 进 GRUB 菜单临时去掉参数先把系统救回来,再回到备份文件核对哪里写错了。systemd-boot 场景下的救援方式更依赖具体安装介质,属于救援启动的内容。

参考资料 ​

Proxmox VE 非官方中文使用指南,与 Proxmox Server Solutions GmbH 无隶属关系。