Proxmox VE 7.1安装macOS 10.15及GPU穿通方案

本文的背景是,出于需要搭建一套能充分使用GPGPU硬件加速的macOS环境。而本人家境贫寒,无力负担起搭载高性能AMD GPU的Mac,需要找到一套更加廉价的方案。安装完成的效果图如下,左边是Windows PC,右边是虚拟机中的macOS:

Proxmox VE (PVE) 是一个基于KVM和QEMU的开源虚拟化平台,搭建非授权的macOS也就是黑苹果相对直接使用物理机有不少优势:

遇到引导问题时不用重启物理机,节约了大量时间
PVE本体是个修改后的Debian 10,有大量linux下的实用工具可以使用
Host可以直接挂载macOS硬盘分区,便于修改引导
以下默认读者已经基本熟悉PVE的操作,需要用到的软件有:

ProxmoxVE 7.1+
OpenCore 0.6.1
任意文本编辑器
7-Zip
OpenCore Configurator
本文从已经完成安装,配置好vim, parted, kpartx等工具的PVE环境开始

强烈建议在PVE中使用Samba将工作目录共享给另一台有桌面环境的电脑(Win或Mac都行)

1.准备安装镜像
首先下载OSX-KVM,解压后将其中的fetch-macOS.py放到任意存储的template/iso下,然后执行脚本:

python3 ./fetch-macOS-v2.py

选择当前最新版的macOS,下载得到一个约600M的BaseSystem.dmg

使用qemu-img 将BaseSystem.dmg转换为PVE可以加载的格式。

qemu-img convert BaseSystem.dmg -O raw Catalina-installer.iso

然后下载kholia/OSX-KVM,用7-Zip打开

OpenCore-Catalina/OpenCore.qcow2

,解压出第一个EFI System的primary.img

primary.img重命名为OpenCore.iso,放到template/iso下,准备好安装镜像后就可以创建虚拟机了。

2.创建虚拟机
点击创建虚拟机,勾选高级,随意设置VM ID和名称。

选择OpenCore.iso,访客OS选择Other

显卡设为VMWare兼容,BIOS设为OVMF(UEFI),机器设为q35,存储随意

选择SATA,缓存Write back(不安全),丢弃,SSD仿真。

CPU设置到4核心以上,选择host(因特尔)或者Penryn(AMD)

内存8G以上,关闭Ballooning

网络选择WMware wmxnet3

点击完成后,为虚拟机添加光驱,载入Catalina-installer.iso

修改/etc/pve/qemu-server/下的虚拟机配置文件,与创建时的VM ID同名,比如文中的是100.conf,在文本开头添加一行:

args: -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -smbios type=2 -device usb-kbd,bus=ehci.0,port=2

如果cpu是intel,则在同一行行末加上:

-cpu host,kvm=on,vendor=GenuineIntel,+kvm_pv_unhalt,+kvm_pv_eoi,+hypervisor,+invtsc 

如果cpu是amd,则在同一行行末加上:

-cpu Penryn,kvm=on,vendor=GenuineIntel,+kvm_pv_unhalt,+kvm_pv_eoi,+hypervisor,+invtsc,+pcid,+ssse3,+sse4.2,+popcnt,+avx,+avx2,+aes,+fma,+fma4,+bmi1,+bmi2,+xsave,+xsaveopt,check

将两处media=cdrom修改为cache=unsafe,最终100.conf为(Intel平台);

args: -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -smbios type=2 -device usb-kbd,bus=ehci.0,port=2 -cpu host,kvm=on,vendor=GenuineIntel,+kvm_pv_unhalt,+kvm_pv_eoi,+hypervisor,+invtsc
balloon: 0
bios: ovmf
boot: cdn
bootdisk: ide2
cores: 4
cpu: Penryn
efidisk0: local-lvm:vm-100-disk-1,size=4M
ide0: MediaCache0:iso/Catalina-installer.iso,cache=unsafe,size=2086412K
ide2: MediaCache0:iso/OpenCore.iso,cache=unsafe
machine: q35
memory: 8192
name: macOS

修改启动顺序为OpenCore.iso在最上面

最后修改kvm设置,激活ignore_msrs,更新initramfs后重启Host。

echo "options kvm ignore_msrs=Y" >> /etc/modprobe.d/kvm.conf
update-initramfs -k all -u
reboot

3.安装macOS
虚拟机启动后按ecs键,进入BIOS设置

Device Manager/OVMF Platform Configuration下的分辨率改为1920x1080,按F10保存后,退出BIOS。
进入OpenCore引导后,选择macOS Base System进入安装

进入安装后不会显示选择语言,在菜单里选择修改语言,会卡一段时间

用磁盘工具抹掉虚拟硬盘

选择重新安装macOS

一路继续下去,选择刚才格式化的硬盘

等待一段时间

重启后选择macOS Installer继续

安装完毕后自动重启,选择macOS引导进系统

安装向导记得跳过登录Apple ID

此时需要把OpenCore安装到虚拟硬盘中。打开终端,输入diskutil list,得到当前磁盘列表

disk0是OpenCore.iso中的EFI分区,disk2s1是虚拟磁盘中的EFI分区,使用dd命令将OpenCorex写入虚拟硬盘,实际分区id可能会不同

sudo dd if=/dev/disk0 of=/dev/disk2s1

提示Resources busy的话就先diskutil umount对应的分区

写入完成后就可以关机分离挂载的iso,记得修改引导顺序。

4.在Host上挂载虚拟硬盘的方法
为了编辑OpenCore的配置文件,需要将guest的虚拟磁盘挂载到host的目录中。

由于使用了lvm,所以需要先用kpartx装载虚拟文件系统。

kpartx -a /dev/mapper/pve-vm--100--disk--0

会产生pve-vm--100--disk--0p1和pve-vm--100--disk--0p2两个设备文件,我们需要挂载EFI分区也就是pve-vm--100--disk--0p1,这里推荐在共享目录下创建挂载点

mount /dev/mapper/pve-vm--100--disk--0p1 /mnt/pve/MediaCache0/efi

之后在连接共享目录的Windows中也可编辑EFI分区了。

5.PVE中PCIe穿通设置
首先得确认host平台支持IOMMU,先编辑grub引导配置/etc/default/grub,填入intel_iommu=on或者amd_iommu=on,以及video=efifb:off防止host加载显卡:

...
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on video=efifb:off" 
...

然后运行

pve-efiboot-tool refresh
update-grub
reboot

使用

dmesg | grep -e DMAR -e IOMMU

查看IOMMU是否启用:

之后修改/etc/modules加入vfio模块:

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

使用lspci -nn查看显卡的设备id:

记下设备id 1002:7341和1002:ab38,编辑/etc/modprobe.d/vfio.conf

options vfio-pci ids=1002:7341,1002:ab38 disable_vga=1

编辑/etc/modprobe.d/blacklist.conf,将显卡驱动加入黑名单:

blacklist nvidiafb
blacklist nouveau
blacklist nvidia
blacklist radeon
blacklist amdgpu
blacklist snd_hda_intel
blacklist snd_hda_codec_hdmi
blacklist snd_hda_codec
blacklist snd_hda_core

再次确保四个文件都正确编辑:

/etc/default/grub
/etc/modules
/etc/modprobe.d/vfio.conf
/etc/modprobe.d/blacklist.conf

然后更新

update-initramfs -k all -u

,然后关机。重启后使用lspci查看显卡是否已经启用vfio-pci

lspci -v

6.将显卡穿通给虚拟机
在网页中为虚拟机添加pcie设备

勾选全部选项

关闭虚拟显示输出

记得添加键鼠的直通。然后挂载EFI分区,删除里面的内容,将 OpenCore-Catalina\OpenCore-Passthrough.qcow2 中的EFI镜像解压到EFI分区中:

然后关闭host,把显示器插到独显上,然后开机,由于显卡驱动被屏蔽,所以这时显示器没有输出,从这里开始一定要使用ssh连接host进行操作。

尝试启动macOS,如果苹果标读条读到70%左右时黑屏,就删除config.plist中的WhateverGreen.kext项目。

理论上现在已经可以正常进入macOS桌面了。

使用VideoProc查看显卡是否成功驱动:

GeekBench5 Compute跑分达到了39000分,为苹果官方Pro W5700X MPX模块的56%,而售价仅为后者的40%,性价比较高。

8.常见问题
由于Vega和Navi GPU缺少Function Level Reset(FLR)的支持,会导致虚拟机关机后显卡睡死而无法重新启动虚拟机。解决方法是卸载显卡和板载声卡后,休眠物理机,然后重新扫描pcie设备,可以制作如下脚本:

echo "1" > /sys/bus/pci/devices/0000\:03\:00.0/remove
echo "1" > /sys/bus/pci/devices/0000\:03\:00.1/remove
echo mem > /sys/power/state
echo "1" > /sys/bus/pci/rescan

在第三行执行后虚拟机会进入休眠,此时需要手动按下开关恢复运行,这对运维有了一定的阻碍。另一个方法是给kernel打补丁,链接留在这里本文暂不展开。
https://forum.level1techs.com/t/navi-reset-kernel-patch/147547

点赞