☰
Ubuntu 22.04 装 VirtualBox 7.0 踩坑:内核驱动与VT-x 报错修复指南
2026/10/23 1:17:45 网站建设 项目流程

最近在某台 Ubuntu 22.04 的工作机上装 VirtualBox 7.0,打算开一个 Win10 虚拟机做测试环境,结果连续碰到两个经典报错:一个卡在内核驱动加载,一个卡在硬件虚拟化开启。这两个报错单看任何一个都不算冷门,但凑在一起,而且都是在全新安装环境下出现的,排查起来确实有点绕。把整个分析和修复过程整理出来,给同样在这个组合上栽过跟头的朋友做个参考。

1. 环境定位:Ubuntu 22.04 + VirtualBox 7.0 的组合为什么会出问题

先说清楚我当时的宿主机环境:Ubuntu 22.04 LTS,内核版本 5.15.0-xxx-generic,CPU 是 Intel 平台,支持 VT-x。VirtualBox 用的是 Oracle 官方仓库的 7.0 系列,具体小版本是当时最新的 7.0.12。目标虚拟机是 Windows 10 22H2,分配 4 核 CPU、8GB 内存、128GB 动态虚拟磁盘。

1.1 版本选型的底层逻辑

选择 Ubuntu 22.04 作为宿主机,是因为它的 LTS 性质决定了内核和用户态组件相对稳定,VirtualBox 7.0 对 5.15 内核的支持也比较成熟。但这里有个很多人忽略的细节:Ubuntu 22.04 默认启用 Secure Boot,而 VirtualBox 的内核模块 vboxdrv、vboxnetflt、vboxnetadp 都是需要加载到内核空间的驱动,Secure Boot 开启时,内核只会加载经过签名验证的模块。这为后面的 Kernel driver 报错埋下了第一个雷。

另一个细节是 VirtualBox 7.0 对内核模块的构建方式。它依赖 Linux 内核头文件和编译工具链,安装后需要通过 dkms 或者手动调用/sbin/vboxconfig来编译模块。如果你的系统恰好升级过内核,或者安装 VirtualBox 时对应的内核头文件不完整,模块编译就会失败,表现就是启动虚拟机时报 Kernel driver 未安装。

1.2 报错的宏观分类:内核模块层与虚拟化指令层

这两类报错虽然都表现为“虚拟机无法启动”,但问题所在的层级完全不同。

Kernel driver 报错,本质是宿主机内核与 VirtualBox 之间的桥接层出了问题。VirtualBox 作为 Type-2 虚拟机监控器,必须依赖一个内核驱动来执行特权指令、管理物理内存和中断。这个驱动加载不上,虚拟机就失去了运行的基础。它属于“宿主机内核层”的问题。

VT-x 报错,本质是 CPU 硬件虚拟化能力没有被正确暴露或开启。VT-x(Intel Virtualization Technology)是 CPU 级别的一组扩展指令集,虚拟机监控器需要借助它来创建隔离的硬件上下文。如果 BIOS/UEFI 里关闭了虚拟化,或者宿主机自身就是虚拟机且没有开启嵌套虚拟化,VirtualBox 就会明确提示 VT-x 被禁用。它属于“CPU 固件层和硬件特性层”的问题。

把这两类问题分开看,排查路径就清晰很多。

2. Kernel driver 报错的根因分析与修复

2.1 现象与报错原文

启动 Win10 虚拟机时,VirtualBox 弹出一个错误框,标题是 "VirtualBox - Error In supR3HardenedMainInitRuntime",正文关键句子是:

Kernel driver not installed (rc=-1908) The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv.

同时,如果你在终端里手动运行virtualbox启动图形界面,再尝试启动虚拟机,还会看到类似这样的补充日志:

WARNING: The character device /dev/vboxdrv does not exist. Please install the virtualbox-dkms package and the appropriate headers.

这个 rc=-1908 错误码,几乎可以锁定为 vboxdrv 内核模块没有成功加载。

2.2 根因一:内核模块未编译或未加载

先在终端里检查模块状态:

lsmod | grep vbox

如果输出为空,说明 vboxdrv 根本没有加载。接下来查看模块编译状态:

sudo /sbin/vboxconfig

这时大概率会看到一行报错:

Building the main VirtualBox module ... fail!

按顺序排查,最常见的原因是缺少内核头文件。Ubuntu 22.04 的内核头文件包名是linux-headers-generic,但它不是 VirtualBox 安装时自动拉取的强依赖。如果你的系统之前做过内核定制或者清理过/lib/modules/下的目录,头文件很可能不完整。

补装头文件并重新构建:

sudo apt update sudo apt install linux-headers-generic build-essential sudo /sbin/vboxconfig

如果一切正常,你会看到三个模块的编译输出:vboxdrv、vboxnetflt、vboxnetadp,然后提示 "VirtualBox kernel modules are loaded"。

这里要给一个实操经验:不要用modprobe vboxdrv手动加载。因为 VirtualBox 在启动时会通过自身的初始化逻辑来加载模块,手动加载容易造成版本不一致。正确做法是跑完/sbin/vboxconfig后,再执行systemctl restart virtualbox.service(如果存在)或者直接重启宿主机。

2.3 根因二:Secure Boot 签名拦截

如果你按照上面步骤执行了/sbin/vboxconfig,但输出里出现的是这样的信息:

vboxdrv.sh: Stopping VirtualBox services. vboxdrv.sh: Starting VirtualBox services. vboxdrv.sh: Building the VirtualBox kernel modules. vboxdrv.sh: failed: Secure Boot is enabled. The kernel module 'vboxdrv' needs to be signed before it can be loaded.

这说明问题不是头文件缺失,而是 Secure Boot 在拦截未签名的内核模块。现代 Ubuntu 发行版默认开启 Secure Boot,编译出来的 vboxdrv.ko 没有 Microsoft 或发行版信任的签名,内核拒绝加载。

解决方案有两种路径,我分别说。

路径 A:关闭 Secure Boot(适合个人开发机)

这个方法直截了当,但需要进 UEFI 设置。重启宿主机,在开机时按下 F2 / DEL / F10(不同主板不一样)进入固件设置,找到 Secure Boot 或 Security Boot,将其设置为 Disabled。保存退出后,再执行:

sudo /sbin/vboxconfig

模块就能正常编译加载了。

注意:关闭 Secure Boot 会降低系统启动链的安全性,适合个人开发环境,生产环境不建议。

路径 B:使用 Machine Owner Key(MOK)签名(适合不想动固件设置的人)

这个方法保留 Secure Boot,但需要自己生成一个签名密钥并导入固件信任列表。步骤较多,但一次配置,之后重新编译内核模块都能用。

安装签名工具并生成密钥:

sudo apt install mokutil shim-signed openssl openssl req -new -x509 -newkey rsa:2048 -keyout vbox.priv -outform DER -out vbox.der -nodes -days 36500 -subj "/CN=VirtualBox Module Signing/"

导入密钥到 MOK 列表:

sudo mokutil --import vbox.der

这时系统会要求你设置一个临时密码,记住它。重启后,会进入蓝色 MokManager 界面,选择 "Enroll MOK from disk",定位到刚才的 vbox.der 文件,确认导入,输入临时密码,继续启动。重启完成后,再用这个密钥给模块签名:

sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 vbox.priv vbox.der /lib/modules/$(uname -r)/updates/dkms/vboxdrv.ko

然后再执行/sbin/vboxconfig验证。这个方法对包括 NVIDIA 驱动在内的其他外部内核模块同样适用,配置一次长期受益。

2.4 修复后的验证方法

模块加载是否成功,不能只看启动虚拟机的窗口。要做三件事:

第一,检查内核模块列表:

lsmod | grep vbox

正常状态应该看到 vboxdrv、vboxnetflt、vboxnetadp 三个模块,其中 vboxdrv 的 Used by 列会提示当前有几个虚拟机在使用它。

第二,检查设备节点:

ls -l /dev/vboxdrv

应该存在一个字符设备文件,属主是 root,组是 vboxusers。如果这个文件不存在,说明模块没加载成功。

第三,把自己使用的系统用户加入 vboxusers 组:

sudo usermod -aG vboxusers $USER

改完组后需要重新登录一次会话,否则访问 /dev/vboxdrv 时依然会被拒绝。这一步很多人容易漏,导致模块明明加载了,启动虚拟机时还是报权限错误。

3. VT-x 报错的根因分析与修复

3.1 现象与报错原文

Kernel driver 修好之后,再次启动 Win10 虚拟机,结果又弹出一个新的错误框:

VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED).

在 VirtualBox 7.0 里,如果是在虚拟化环境里跑(比如在某云主机里又套了一层 VirtualBox),可能还会看到:

AMD-V is disabled in the BIOS (or by the host OS) (VERR_SVM_MSR_ALL_DISABLED).

前者是 Intel 平台的典型提示,后者是 AMD 平台。我这边是 Intel CPU,所以重点是 VT-x。

3.2 根因一:BIOS/UEFI 层面关闭了硬件虚拟化

这个根因很朴素,但也很容易被忽略。很多 OEM 主机的出厂设置里,Intel Virtualization Technology 默认是 Disabled。特别是一些商务品牌机和迷你主机,厂商为了省电或稳定考虑,默认关闭这个选项,需要手动去固件设置里打开。

进 UEFI 设置的方法同上文一样,在开机时按 F2 / DEL / F10。不同品牌路径不同,一般在 "Advanced"、"Processor Configuration" 或 "Security" 菜单下,找 "Intel Virtualization Technology" 或 "VT-x",设置为 Enabled。Save & Exit 之后,在宿主机里执行下面命令,确认虚拟化已开启:

grep -E -c '(vmx|svm)' /proc/cpuinfo

输出值大于 0,就代表虚拟化标志位已经暴露给操作系统了。另外,lscpu里也会显示:

Virtualization: VT-x

如果输出了Virtualization标签但没有后面的类型,说明固件设置可能没生效,需要确认是否保存成功。

3.3 根因二:宿主机本身就是虚拟机,嵌套虚拟化未开启

这一步是很多人卡住的地方。如果你的“宿主机”其实是云服务器、公司虚拟机平台里的一台 VM,那么在 VM 里再装 VirtualBox 属于嵌套虚拟化(Nested Virtualization)。这种场景下,仅靠宿主机 BIOS 打开 VT-x 是不够的,还取决于外层虚拟化平台是否把硬件虚拟化指令透传给内层系统。

解决方案是登录外层虚拟化平台的管理界面,为这台 VM 打开嵌套虚拟化选项。比如在常见的管理平台上,需要设置 CPU 模式为 Host Passthrough 或勾选 Expose hardware virtualization to the guest OS;在命令行环境下,可能需要给 VM 的配置加一个 CPU 特性标志。这个操作无法在 Ubuntu 系统内部完成,必须借助外层平台的管理端。

我遇到的正是这个场景:XX云平台上的一台 VM,默认没有暴露 VT-x 给客户机。在管理界面开启嵌套虚拟化后,Ubuntu 里grep vmx /proc/cpuinfo才真正出现标志位。

提示:嵌套虚拟化场景下,即使 VT-x 成功透传,虚拟机性能也会有额外损耗,尤其是在内存访问和中断处理上。如果只是临时做实验问题不大,但不要指望跑重负载的 Windows 虚拟机。

3.4 修复实验证

VT-x 修好后,VirtualBox 里还需要注意一个细节:虚拟机的系统设置中,“硬件虚拟化”相关选项通常默认是全自动的,但如果你曾经手动调整过,需要确保 Processor 选项卡里的 "Enable VT-x/AMD-V" 是勾选状态。这个选项在 7.0 版本里位于:

设置 -> 系统 -> 处理器 -> 硬件虚拟化 -> 启用 VT-x/AMD-V(如果是 Intel 平台还可能显示 "Enable Nested VT-x/AMD-V")

注意,那个 "Enable Nested VT-x/AMD-V" 选项是给虚拟机内部再跑虚拟机用的,我们这里是 Windows 10 客户机,不需要勾选。如果误开了,反而可能引起性能下降。

验证 VT-x 是否被客户机正确识别,最直接的方式是进入 Windows 10 后打开任务管理器 -> 性能 -> CPU,查看“虚拟化”一栏是否显示“已启用”。也可以在 Windows 里运行systeminfo,在 Hyper-V 相关条目下看虚拟化固件状态。

4. 一次性完整实操:从零到 Win10 跑起来

既然两类核心报错都拆完了,我索性把这台机器从装 VirtualBox 到 Win10 系统正常运行的完整流程写一遍,包含关键参数和踩坑点。

4.1 安装 VirtualBox 7.0 的推荐方式

不要在 Ubuntu 软件中心里装 6.1 老版本,也不要只apt install virtualbox装发行版仓库里的版本,关于 7.0 的功能更新我就不多说了,直接说安装方法。最稳的是用 Oracle 官方 apt 仓库。

添加仓库和安装:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/oracle-virtualbox-2016.gpg] https://download.virtualbox.org/virtualbox/debian jammy contrib" | sudo tee /etc/apt/sources.list.d/virtualbox.list wget -O- https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmor --yes --output /usr/share/keyrings/oracle-virtualbox-2016.gpg sudo apt update sudo apt install virtualbox-7.0 dkms

这里把 dkms 一起装上,是为了后续内核更新时模块能自动重建。如果你不想用官方仓库,也可以直接去官网下 .deb 包,但依赖处理不如仓库方式省心。

安装完确认版本:

VBoxManage --version

4.2 创建 Win10 虚拟机时的关键参数

在图形界面里新建虚拟机,选择类型 Microsoft Windows、版本 Windows 10 (64-bit),然后分配资源。我的建议参数是:

参数推荐值备注
内存至少 4096 MB建议 8192 MB,Win10 跑起来更顺
CPU2 核起步4 核体验更好,但别超过物理机一半
显存128 MB低于 64 MB 会明显卡顿
磁盘动态分配 64GB 以上动态分配不占满物理空间
网络默认 NAT先保证能上网,后再加桥接网卡
存储控制器SATA 默认即可不要刻意换 NVMExpress,兼容性优先

创建磁盘时注意勾选“动态分配”,这样最初只占用几个 GB 物理空间,随着 Windows 内部使用逐渐增长。固定大小磁盘虽然性能稍好,但对 SSD 空间不友好。

装系统前有一件容易被忽略的小事:在虚拟机设置 -> 系统 -> 主板 里,把“启用 EFI”选项根据情况勾选。Win10 原生支持 UEFI 启动,如果虚拟机不开 EFI,用传统 BIOS 引导也能装,但分区表会是 MBR,后续想扩容磁盘会麻烦一些。我建议直接勾选 EFI,磁盘分区用 GPT。

4.3 装完系统后的增强功能与性能调优

Windows 10 装好后,第一件事不是打补丁,而是安装 VirtualBox Guest Additions。在虚拟机窗口菜单栏选择:

设备 -> 插入 Guest Additions CD 映像

Windows 里会自动弹出安装向导,或者手动打开 CD 驱动器运行VBoxWindowsAdditions-amd64.exe。安装完成后重启虚拟机,分辨率可以自动适配窗口大小,也能开启共享剪贴板和拖拽文件。这一步不做,虚拟机体验会非常难受。

性能调优方面,我习惯做三件事:

第一,关闭 Windows 的透明度和动画效果。在 Windows 设置 -> 个性化 -> 颜色 里关掉“透明效果”,在性能选项里调整为“调整为最佳性能”。虚拟机的 CPU 资源本来就有限,动画效果纯粹浪费指令周期。

第二,把虚拟机的显示驱动换成 Guest Additions 提供的 VirtualBox Graphics Adapter,而不是基础的 Microsoft Basic Display Adapter。后者不支持硬件加速,窗口拖动都卡。

第三,在 VirtualBox 设置 -> 系统 -> 处理器 里,把“启用 PAE/NX”和“启用 VT-x/AMD-V”都勾上。PAE/NX 对 64 位系统是必须的,虽然默认是好。

5. 高频问题速查与避坑清单实录

把我在这个过程中遇到过的、以及周围同事常问的问题整理成一张速查表,方便直接对照。

报错信息问题层级排查顺序
Kernel driver not installed (rc=-1908)内核模块层1. `lsmod
/dev/vboxdrv 不存在模块加载或权限1. dkms modules 2.usermod -aG vboxusers3. 重新登录
VT-x is disabled in the BIOS (VERR_VMX_MSR_ALL_VMX_DISABLED)CPU 固件层1. UEFI 开启 VT-x 2. 确认grep vmx /proc/cpuinfo3. 外层虚拟化平台透传
AMD-V is disabled (VERR_SVM_MSR_ALL_DISABLED)CPU 固件层AMD 平台同理,确认 svm 标志位
Kernel driver version mismatch版本兼容sudo /sbin/vboxconfig重编;确认没有残留旧模块
虚拟机启动后黑屏显存或 EFI显存调到 128MB;关闭 EFI 用传统 BIOS 引导试试
复制粘贴失效Guest Additions重装 Guest Additions,确认版本与 VirtualBox 一致

5.1 两个容易被忽略但很关键的细节

第一个细节是内核更新后的沉默故障。Ubuntu 22.04 如果开启了自动安全更新,内核可能从 5.15.0-xxx 升级到 5.15.0-yyy。这时候 dkms 理论上会自动重建 VirtualBox 模块,但如果你没有安装 dkms,或者 dkms 编译时缺少新内核的头文件,就会出现这样一种诡异现象:系统重启后,VirtualBox 启动正常,但从终端里跑虚拟机直接报 Kernel driver 未安装,而图形界面打开又看起来一切正常。

这个现象的原因是 VirtualBox 图形界面启动时自动调用了模块加载逻辑,但因为模块编译失败,加载逻辑也失败了。排查方法就是执行/sbin/vboxconfig,把缺的头文件补上。

第二个细节是内核模块签名在 Ubuntu 22.04 上的隐藏坑。如果你执行mokutil --import导入过密钥,之后再升级 VirtualBox 小版本,模块会被重新编译,之前签名的文件失效。你需要重新执行一次 sign-file 命令,或者干脆把签名的动作交给 dkms 的 post-install 钩子。我现在的做法是写了一个简单脚本放在/etc/kernel/postinst.d/里,每次内核更新后自动对新编译的 vboxdrv.ko 做签名。脚本逻辑很简单,核心就是判断当前 Secure Boot 是否启用、找到新版模块文件、调用 sign-file。

5.2 关于“为什么不用 KVM 而用 VirtualBox”一点个人看法

写到最后还是要提一句。在 Ubuntu 22.04 上用 KVM/QEMU 跑 Windows 虚拟机,性能上限比 VirtualBox 高,尤其是有大量 IO 的场景。但 VirtualBox 7.0 的优势在于配置图形化、跨平台迁移方便、以及网卡和 USB 设备的兼容性好。如果只是需要偶尔跑一个 Windows 环境做测试,VirtualBox 的学习成本和维护成本要低很多。

我个人的使用习惯是:长期跑的开发环境虚拟机用 KVM,偶尔临时开的测试虚拟机用 VirtualBox。两类工具解决的问题不完全一样,不存在谁完全取代谁的问题。

回到这次的问题本身。Kernel driver 和 VT-x 这两类报错,根本原因有一个共同点:都是宿主机底层环境没有完整地准备好。内核模块问题解决的是“VirtualBox 能不能控制硬件”,VT-x 问题解决的是“CPU 愿不愿意被控制”。把这两个前提搞定,后续的虚拟机安装其实就是一路下一步的问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询