编译OMVF
需要BIOS支持SRIOV,手动编译OMVF
git clone https://github.com/tianocore/edk2
git submodule update --init --recursive
source edksetup.sh
build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC -D DEBUG_ON_SERIAL_PORT
编译可模拟SRIOV设备的QEMU
QEMU v.7.1.0之后支持模拟SRIOV设备,但是VF功能不正常的,只能用来观察SRIOV的一些分配过程。
wget https://download.qemu.org/qemu-8.1.3.tar.xz
./configure --enable-spice --enable-slirp
make
sudo make install
安装Debian
注意Legacy引导模式安装的系统无法使用UEFI引导,所以要选择OMVF为BIOS再安装系统。
先创建一个空的qcow2镜像用来安装Debian
qemu-img create -f qcow2 ./debian12_uefi.qcow2 5G
sudo qemu-system-x86_64 -name debian12 -M q35 -m 512 \
-cdrom ./debian-12.1.0-amd64-netinst.iso \
-hda ./debian12_uefi.qcow2 -boot d \
-bios ./edk2/Build/OvmfX64/DEBUG_GCC/FV/OVMF.fd -serial stdio \
-net user,hostfwd=tcp::2222-:22 -net nic \
开启-serial stdio
可以输出OVMF启动时的Debug信息(需编译时加上编译选项DEBUG_ON_SERIAL_PORT)
sudo qemu-system-x86_64 -name debian12 -M q35 -m 512 \
-hda ./debian12_uefi.qcow2 -boot d \
-device nvme-subsys,id=subsys0 -device nvme,id=nvme0,bus=pcie.0,addr=4.0,serial=deadbead,subsys=subsys0,sriov_max_vfs=3,sriov_vq_flexible=6,sriov_vi_flexible=3 \
-bios ./edk2/Build/OvmfX64/DEBUG_GCC/FV/OVMF.fd -serial stdio \
-net user,hostfwd=tcp::2222-:22 -net nic \
-virtfs local,path=./share,mount_tag=host0,security_model=passthrough,id=host0
虚拟SRIOV Device的用法参考下面这个说明:
Knut's QEMU patchwork · knuto/qemu Wiki · GitHub
启动QEMU后可以看到UEFI枚举PCI设备的打印,扫描到00:04.00的设备带有SR-IOV Cap,并且分配了VF BAR的空间。
Debian下也可以识别到NVMe设备
修改内核
不过QEMU虚拟的VF HDR Type有问题,系统读出来出来是7F,开启VF会出错,只能强行修改内核让他跳过判断。
修改drivers/pci/probe.c
,Header类型判断前强行把7F改为0
if (dev->hdr_type == 0x7f)
dev->hdr_type = 0; /* fix for qemu nvme vf */
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
....
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
....
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
....
default: /* unknown header */
....
}
cp /boot/config-`uname -r` ./.config
make menuconfig
fakeroot make -j4 deb-pkg
开启VF
echo 3 > /sys/bus/pci/devices/0000\:00\:04.0/sriov_numvfs
由于这几个VF是不能正常工作的,所以NVMe驱动会报错,这里不管他,lspci
已经能看到多个设备。
压缩Qcow2镜像
qemu-img convert -c -O qcow2 debian12_uefi.qcow2 debian12_uefi_convert.qcow2