OSX-KVM笔记
文章目录
1. 前言
在家里一连复习了几天,想着要休息一下,于是就试试用KVM装了个黑苹果。
折腾了两天总算可以运行起来,完成度50%,不是很满意,最后还是装回了Windows。
这里记录下操作过程,以后Github上的开源项目完善,有时间再折腾时,可以做参考。
2. 机器配置
- CPU:E5-2680v2 X 2
- 内存:8GB ECC X 4
- 显卡:RX580
- 主板:华南金牌X79双路
- 硬盘:阿斯加特500GB NVME
- 散热:PWM风扇 X N
- 电源:鑫谷全模750电源(650W)
黑苹果需要打上许多补丁才能运行,冷门的配置和X79山寨板几乎是无法驱动的,于是很自然的就想到了虚拟化的方式。
虚拟化的方式并不稀奇,CPU在虚拟化的情况下性能损失不多,主要问题是图形界面,常用的VirtualBox、VMware都有安装黑苹果的教程,即使开启了3D加速,图形界面依旧是PPT般的卡顿,这个时候突然想到了KVM的PCIe透传。
RHEL5开始就有相关的文档介绍如何将Host的PCI设备附加到客户机上:CHAPTER 15. PCI PASSTHROUGH。
PCIe总线是直连CPU的,BIOS中开启VT-d后,配合启用IOMMU的内核,可以将任何走PCIe总线的宿主机设备直接分配给客户机,包括:USB控制器、网卡、蓝牙、GPU、NVME固态硬盘等等。相比虚拟化设备的方式,性能接近原生。
目前家里的电脑太多了,算下来一共有过7台台式机和5个笔记本,这是博主的第二台E5主机,第一台E5已经打包准备送人了。因此最初的计划是在这台双路E5上安装Linux系统,再通过虚拟化的方式运行macOS、Windows和其他图形化桌面的Linux。
Windows和Linux在兼容性方面没有太多问题,本身就适配了众多的机器,但macOS还需要一些补丁来适配黑苹果机器,自己能想到自然早就有更多人想到,下面是目前Github上的两个热门项目。
3. 项目地址
kholia/OSX-KVM
地址:https://github.com/kholia/OSX-KVM
foxlet/macOS-Simple-KVM
https://github.com/foxlet/macOS-Simple-KVM
注意,两个教程的前提都是:
- 图形化桌面的Linux宿主机环境
- 双显卡,双独显、集显+独显都可以
- 2011年后的英特尔CPU或AMD的RYZEN系列CPU
教程的步骤基本类似:
- 系统镜像下载与和转换:不需要一个额外的MacBook了,使用Python2或Python3的环境就可以
- 安装qemu,使用kvm作为底层驱动
- 安装libvirtd,启动virsh0网卡,额外配置一个tap0网卡供虚拟机使用
- 初始化一个虚拟机系统盘,安装系统:这一步耗时最长,可以在图形化的Linux环境下安装或者使用VNC远程访问
- 启动已安装好的macOS系统,在系统内安装Clover引导,打补丁,配置驱动
- 其他配置,如PCIe透传
4. 软件安装与配置
在过去两天里,博主使用 OSX-KVM 的配置文件,测试了三个系统:CentOS 8、Ubuntu 18.04、Ubuntu 20.04,最后在Ubuntu 20.04上完成了安装。
Ubuntu 20.04的VFIO驱动还存在问题,虽然Linux 5.4内核整合了VFIO,但使用时异常,只能在Grub启动命令中隔离PCIe设备。整个安装最终挂在 USB控制器 透传上,键鼠设备始终无法直接在虚拟机环境下使用。
这里推荐使用Ubuntu 18.04,Linux内核版本为4.18。在不进行PCIe透传前,三个系统的配置大同小异,而关于VFIO的配置教程,目前是Ubuntu 18.04最多, OSX-KVM 教程默认也使用这个系统。
博主没有安装桌面系统,直接使用命令行的方式操作,安装系统后通过ssh远程配置,下面所有的命令都是在 OSX-KVM 目录下以root用户权限操作,安装macOS 10.15,如下:
1. 安装基础软件
1apt install --no-install-recommends qemu-system-x86 qemu-kvm uml-utilities dmg2img git wget libguestfs-tools ovmf libvirt-daemon-system
上述命令主要安装了命令行版本的qemu、VFIO驱动、libvirtd等
2. kvm模块配置
按照OSX-KVM的教程,将 kvm.conf 文件复制到 /etc/modprobe.d/kvm.conf
3. 下载与转换系统镜像
执行 fetch-macOS.py 命令下载macOS 10.15,它会使用Python通过苹果的CDN下载 BaseSystem.dmg,然后使用上面安装的 dmg2img 工具转换格式,输出文件 BaseSystem.img。
4. 网络配置
安装好 libvirt-daemon-system 后,就会默认启动一个 virbr0 网卡,我们再添加一个 tap0 供虚拟机使用:
1ip tuntap add dev tap0 mode tap
2ip link set tap0 up promisc on
3ip link set dev tap0 master virbr0
关机重启后 tap0 会失效,可以配置一个systemd服务开机运行上述脚本。
5. 系统安装
首先创建一个系统盘,这里大小直接取512GB,文件大小随使用增长:
1qemu-img create -f qcow2 mac_hdd_ng.img 512G
启动系统,这里在OSX-KVM提供的boot-macOS-Catalina.sh命令中添加了VNC配置:
1qemu-system-x86_64 -enable-kvm -m 3072 -cpu Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,$MY_OPTIONS\
2 -machine q35 \
3 -smp 4,cores=2 \
4 -usb -device usb-kbd -device usb-mouse \
5 -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" \
6 -drive if=pflash,format=raw,readonly,file=$OVMF/OVMF_CODE.fd \
7 -drive if=pflash,format=raw,file=$OVMF/OVMF_VARS-1024x768.fd \
8 -smbios type=2 \
9 -device ich9-intel-hda -device hda-duplex \
10 -device ich9-ahci,id=sata \
11 -drive id=Clover,if=none,snapshot=on,format=qcow2,file=./'Catalina/CloverNG.qcow2' \
12 -device ide-hd,bus=sata.2,drive=Clover \
13 -device ide-hd,bus=sata.3,drive=InstallMedia \
14 -drive id=InstallMedia,if=none,file=BaseSystem.img,format=raw \
15 -drive id=MacHDD,if=none,file=./mac_hdd_ng.img,format=qcow2 \
16 -device ide-hd,bus=sata.4,drive=MacHDD \
17 -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27 \
18 -monitor stdio \
19 -vnc 0.0.0.0:0 -k en-us
上述的命令作用如下:
- 启动qumu,使用kvm驱动
- 分配3GB内存,双核心四线程CPU
- qumu模拟键鼠
- 注入OVMF驱动
- 模拟声卡
- 模拟sata设备,按启动顺序挂载了Clover引导盘、系统安装盘、系统盘
- 分配网卡,使用tap0
- 输出命令行响应到标准输出
- 启动后默认监听0.0.0.0:5900端口,接收外部VNC连接
5. VNC模式安装系统
对于没有双显卡的用户,宿主机安装系统时可选择Linux服务器版本,不启用图形化桌面,安装macOS时VNC模式是唯一的连接方式,在Windows、Linux和macOS都有各自的VNC客户端,这里以macOS为例。
注意: macOS自带的VNC客户端需要输入密码,在这一步中无法使用,我们需要下载或安装一个TigerVNC客户端
1brew cask install tigervnc-viewer
启动VNC客户端连接宿主机的5900端口后,可以使用当前的键鼠操作安装系统,按顺序格式化硬盘为HFS+、安装系统,这一步耗时约30分钟,安装成功重启后,需要约20分钟完成系统自动配置。
系统完成启动后创建用户,登录系统,下载Clover、安装配置引导,这一步就结束了。
6. VFIO配置
VFIO的配置目的是:
- 获取指定PCIe设备并进行隔离
- 使用vfio-pci驱动代替内核提供的原生驱动运行PCIe设备
步骤如下:
1. 配置BIOS
进入BIOS后,找到VT-d选项并启用,如有提供配置PCIe的Above 4G Decoding,也一并启用。
2. 配置grub启动参数
在 /etc/default/grub 文件的 GRUB_CMDLINE_LINUX_DEFAULT 选项中,加入以下参数
1iommu=pt intel_iommu=on video=efifb:off
3. 禁用驱动
编辑 /etc/modprobe.d/blacklist.conf ,屏蔽常见的显卡驱动
1...
2blacklist radeon
3blacklist nouveau
4blacklist nvidia
5blacklist amdgpu
这里多添加了一个amdgpu,Linux内核默认使用该驱动驱动amd的RX400和RX500系列显卡
4. 启用vfio内核模块
编辑 /etc/modules 添加以下内容:
1vfio
2vfio_iommu_type1
3vfio_pci
4vfio_virqfd
5. 获取PCIe设备
指令命令 lspci -nn获取PCIe设备列表,对应的BF ID和pcie ID,如下
1lspci -nn|grep 'AMD\|USB'
输出
1...
203:00.0 ... AMD VGA [10de:1c82]
303:00.1 ... AMD AUDIO [10de:0fb9]
400:1a.0 USB controller: VIA USB 3.0 Host Controller [1b21:1242]
最左侧的ID:03:00.0等为后续分配给客户机的BF ID,最右侧的10de:1c82等为需要隔离的PCIe设备ID
6. 隔离PCIe设备
在第二步的参数命令中追加需要隔离的显卡和USB控制器的PCIe设备ID,完成的参数如下:
1GRUB_CMDLINE_LINUX_DEFAULT="iommu=pt intel_iommu=on video=efifb:off vfio-pci.ids=10de:1c82,10de:0fb9,1b21:1242"
7. 更新grub与内核模块
1update-grub2
2update-initramfs -k all -u
8. 验证
重启系统后我们可以在dmesg中看到IOMMU和VFIO的信息,执行以下命令可以查看
1dmesg|grep 'IOMMU\|DMAR\|vfio'
7. PCIe透传
完成上述配置后,需要更新qemu启动命令,将键鼠接到隔离的USB端口,显卡连接显示器,然后执行以下命令:
1qemu-system-x86_64 -enable-kvm -m 3072 -cpu Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,$MY_OPTIONS\
2 -machine q35 \
3 -smp 4,cores=2 \
4 -usb -device usb-kbd -device usb-mouse \
5 -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" \
6 -drive if=pflash,format=raw,readonly,file=$OVMF/OVMF_CODE.fd \
7 -drive if=pflash,format=raw,file=$OVMF/OVMF_VARS-1024x768.fd \
8 -smbios type=2 \
9 -device ich9-intel-hda -device hda-duplex \
10 -device ich9-ahci,id=sata \
11 -drive id=Clover,if=none,snapshot=on,format=qcow2,file=./'Catalina/CloverNG.qcow2' \
12 -device ide-hd,bus=sata.2,drive=Clover \
13 -device ide-hd,bus=sata.3,drive=InstallMedia \
14 -drive id=InstallMedia,if=none,file=BaseSystem.img,format=raw \
15 -drive id=MacHDD,if=none,file=./mac_hdd_ng.img,format=qcow2 \
16 -device ide-hd,bus=sata.4,drive=MacHDD \
17 -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27 \
18 -monitor stdio \
19 -vga none
20 -device vfio-pci,host=03:00.0,bus=pcie.0,multifunction=on \
21 -device vfio-pci,host=03:00.1,bus=pcie.0 \
22 -device vfio-pci,host=00:1a.0,bus=pcie.0
上述命令移除了VNC,将显卡和USB控制器接入到客户机的PCIe总线中,启动后就可以在显示器上看到macOS系统启动界面了。
8. 总结
KVM相比其他的虚拟化方式,最大的优点还是可以透传PCIe设备,分配显卡给客户机系统实现3D加速,网上最多的资料可能就是KVM运行Windows,macOS的KVM虚拟化还需要比较多的macOS系统内的配置工作。
虽然RX580在macOS下免驱,外接的4K显示器也正常启动了,但还是卡在了 USB控制器 的透传上,猜测是 OSX-KVM 项目的默认Kext中缺少一些识别通过PCIe总线连接的USB设备的驱动。
再说一些题外话,除了软件外,台式机或者笔记本的整机使用体验也很重要。macOS在温度管理上一直比较保守,用高温代替了噪音,对需要集中精神的工作是有利的。我们在组装台式机时,可以多使用分体式水冷、一体式水冷、减速线和PWM风扇来降低风扇噪音,显卡首选支持低温时风扇自动停转的类型。