Proxmox VE KVM 虚拟化 macOS
source link: https://azhuge233.com/proxmox-ve-kvm-%e8%99%9a%e6%8b%9f%e5%8c%96-macos/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
关于 macOS 虚拟机,我最初的尝试是:无头模式的 Debian 10 虚拟机下开启嵌套虚拟化,然后使用 macOS-Simple-KVM,但是效果并不理想:在 High Sierra 和 Mojave 下,安装程序无法连接到恢复服务器(“The recovery server could not be contacted” 中有人切换到 dhcpd 配置网络后成功连接服务器),而 Catalina 完全无法启动安装程序
之后尝试使用 kholia / OSX-KVM ,但依然无法在无头模式的虚拟机下安装 macOS,之后跟随官方推荐的 nicksherlock.com 中的 PVE 的使用教程,成功创建 macOS 虚拟机
macOS 虚拟机本质上是 OpenCore 引导的黑苹果,新建虚拟机后的安装过程也较为相似,OpenCore 相较于 Clover 省去了很多繁琐的配置步骤,适用于 High Sierra、Mojave、Catalina 和 Big Sur
因为 PVE 也是基于 Debian 和 KVM/QEMU,所以理论上应该适用于所有安装了 KVM/QEMU 的 Linux 系统,区别在于安装过程有没有 GUI
强烈建议机器连接显示器,不要使用无头模式,QEMU 的 -nographic 和 -curses 模式并不好用,并且会产生各种问题导致 macOS 无法安装
下文将展示如何在 Proxmox VE 6.2 下新建 macOS Catalina 虚拟机
- Proxmox VE 6.2
- 支持 SSE 4.2 的 CPU
- Nehalem 及之后架构(带 Core 名称)的 Intel CPU 均支持 SSE 4.2 指令集
- 正常运行的 Linux/Windows 电脑
生成安装镜像
- 安装 python3、git
- 获取 OSX-KVM
- 执行
git clone https://github.com/kholia/OSX-KVM.git
git clone https://github.com/kholia/OSX-KVM.git
- 执行
- 获取 BaseSystem
- 执行
cd OSX-KVM./fetch-macOS.py
cd OSX-KVM ./fetch-macOS.py
- 选择 13,下载最新版本 Catalina 10.15.7
- 执行
- 转换 BaseSystem.dmg 镜像格式
- macOS 下执行
hdiutil convert BaseSystem.dmg -format UDTO -o Catalina-Installer.isomv Catalina-Installer.iso.cdr Catalina-Installer.iso
hdiutil convert BaseSystem.dmg -format UDTO -o Catalina-Installer.iso mv Catalina-Installer.iso.cdr Catalina-Installer.iso
- Linux 下可以安装 dmg2img
dmg2img BaseSystem.dmg Catalina-installer.iso
dmg2img BaseSystem.dmg Catalina-installer.iso
或者可以使用 qemu-img(需要安装 qemu-utils)
qemu-img convert BaseSystem.dmg -O raw Catalina-installer.isoqemu-img convert BaseSystem.dmg -O raw Catalina-installer.iso
- macOS 下执行
- 将 Catalina-installer.iso 镜像上传到 PVE
获取 OpenCore 镜像
访问 thenickdude / KVM-Opencore,下载最新的 OpenCore.iso.gz 文件(目前为 v10),解压得到 OpenCore.iso,上传到 PVE
最终 PVE 中的镜像如下图,应有 Catalina-Installer.iso 和 OpenCore.iso(忽略其他镜像)
新建 Catalina 虚拟机
如图新建虚拟机
新建虚拟机
镜像选择 OpenCore.iso,操作系统选择其他
系统选择 VMWare兼容,BIOS选择 OVMF(UEFI),勾选添加 EFI 磁盘,机器选择 q35
硬盘选择 SATA 0,缓存选择 Write back(不安全),勾选 SSD 仿真(建议新建在 SSD 上,体验较好)
CPU核心按需选择,类别选择 Penryn
内存容量按需设置,取消勾选 Ballooning 设备
网络模型选择 VMWare vmxnet3
配置虚拟机
- 在 虚拟机-选项 中开启 使用平板指针
- 在 虚拟机-硬件 中添加 CD/DVD Drive,总线选择 IDE 0,镜像选择 Catalina-Installer.iso
- 获取 OSK 密钥(需要 macOS,可跳过)
- 可以直接使用:ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc
- 或者手动获取(需要先安装 xcode):新建 smc_read.c 文件,写入以下内容
#include <stdio.h>#include <IOKit/IOKitLib.h>typedef struct {uint32_t key;uint8_t __d0[22];uint32_t datasize;uint8_t __d1[10];uint8_t cmd;uint32_t __d2;uint8_t data[32];} AppleSMCBuffer_t;main(void)io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault,IOServiceMatching("AppleSMC"));if (!service)return -1;io_connect_t port = (io_connect_t)0;kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port);IOObjectRelease(service);if (kr != kIOReturnSuccess)return kr;AppleSMCBuffer_t inputStruct = { 'OSK0', {0}, 32, {0}, 5, }, outputStruct;size_t outputStructCnt = sizeof(outputStruct);kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2,(const void*)&inputStruct, sizeof(inputStruct),(void*)&outputStruct, &outputStructCnt);if (kr != kIOReturnSuccess)return kr;int i = 0;for (i = 0; i < 32; i++)printf("%c", outputStruct.data[i]);inputStruct.key = 'OSK1';kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2,(const void*)&inputStruct, sizeof(inputStruct),(void*)&outputStruct, &outputStructCnt);if (kr == kIOReturnSuccess)for (i = 0; i < 32; i++)printf("%c", outputStruct.data[i]);printf("\n");return IOServiceClose(port);
#include <stdio.h> #include <IOKit/IOKitLib.h> typedef struct { uint32_t key; uint8_t __d0[22]; uint32_t datasize; uint8_t __d1[10]; uint8_t cmd; uint32_t __d2; uint8_t data[32]; } AppleSMCBuffer_t; int main(void) { io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleSMC")); if (!service) return -1; io_connect_t port = (io_connect_t)0; kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port); IOObjectRelease(service); if (kr != kIOReturnSuccess) return kr; AppleSMCBuffer_t inputStruct = { 'OSK0', {0}, 32, {0}, 5, }, outputStruct; size_t outputStructCnt = sizeof(outputStruct); kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2, (const void*)&inputStruct, sizeof(inputStruct), (void*)&outputStruct, &outputStructCnt); if (kr != kIOReturnSuccess) return kr; int i = 0; for (i = 0; i < 32; i++) printf("%c", outputStruct.data[i]); inputStruct.key = 'OSK1'; kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2, (const void*)&inputStruct, sizeof(inputStruct), (void*)&outputStruct, &outputStructCnt); if (kr == kIOReturnSuccess) for (i = 0; i < 32; i++) printf("%c", outputStruct.data[i]); printf("\n"); return IOServiceClose(port); }
- 编译并执行 smc_read
gcc -o smc_read smc_read.c -framework IOKit./smc_read
gcc -o smc_read smc_read.c -framework IOKit ./smc_read
- 编辑虚拟机配置文件
- SSH 连接 PVE,或者使用 PVE 自带 Web SSH
- 打开 /etc/pve/qemu-server/[虚拟机ID].conf,添加新行
args: -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -smbios type=2 -device usb-kbd,bus=ehci.0,port=2
args: -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -smbios type=2 -device usb-kbd,bus=ehci.0,port=2
- 如果使用 Intel CPU,在 args 新增行的行末添加
-cpu host,kvm=on,vendor=GenuineIntel,+kvm_pv_unhalt,+kvm_pv_eoi,+hypervisor,+invtsc
-cpu host,kvm=on,vendor=GenuineIntel,+kvm_pv_unhalt,+kvm_pv_eoi,+hypervisor,+invtsc
如果使用 AMD CPU,在 args 新增行的行末添加
-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-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
- 找到两个 CD 驱动器的配置行,将 “media=cdrom” 更改为 “cache=unsafe”
- 最终的虚拟机配置文件如下
配置 Proxmox VE
启动虚拟机前的最后操作
- 防止 macOS 无限重启
echo 1 > /sys/module/kvm/parameters/ignore_msrs
echo 1 > /sys/module/kvm/parameters/ignore_msrs
- 使设置持续生效
echo "options kvm ignore_msrs=Y" >> /etc/modprobe.d/kvm.conf && update-initramfs -k all -u
echo "options kvm ignore_msrs=Y" >> /etc/modprobe.d/kvm.conf && update-initramfs -k all -u
安装 Catalina
- 启动虚拟机,进入 OpenCore 启动界面
- 选择进入 macOS Base System
- 进入 磁盘工具 格式化硬盘
- 安装 Catalina
- 安装完毕后会重启,再次进入 OpenCore 启动界面,选择进入 macOS Install 磁盘(通常为第二个选项),不要再次进入 macOS Base System
- 等待安装完毕,系统再次重启,这次选择格式化时的磁盘名称,进入 macOS 的欢迎界面,选择跳过登录 Apple ID
- 成功安装 macOS
配置 OpenCore
以下两步将解决 macOS 的 EFI 启动问题并开启自启动
复制 OpenCore EFI
此时虚拟机的启动依赖于挂载的 OpenCore.iso 镜像,此步骤会将 OpenCore 的 EFI 复制到 macOS 所在磁盘
- 进入 macOS 后,打开 终端,查看所有磁盘和分区
diskutil list
diskutil list
如图所示,OpenCore.iso 磁盘内只有一个 EFI 分区,大小约为 150 MB
- 将 OpenCore 磁盘内的 EFI 分区复制到 macOS 的 EFI 分区
sudo dd if=/dev/disk1s1 of=/dev/disk2s1
sudo dd if=/dev/disk1s1 of=/dev/disk2s1
/dev/disk1s1 为 OpenCore 的 EFI 分区,/dev/disk2s1 为 macOS 磁盘的 EFI 分区
- 关机,在 虚拟机-硬件 中删除 OpenCore.iso 和 Catalina-Installer.iso 两个 CD 驱动器
OpenCore 自动启动
经过以上步骤,macOS 虚拟机启动时可以不需要挂载 OpenCore.iso 镜像,但是仍然需要手动选择启动磁盘,以下步骤将开启 OpenCore 自启动
- 进入 macOS,挂载 EFI 分区
- 查看 EFI 分区路径
diskutil list# 找到 EFI 分区路径
diskutil list # 找到 EFI 分区路径
- 挂载分区
sudo mkdir /Volumes/EFIsudo mount -t msdos /dev/[EFI 分区路径] /Volumes/EFI
sudo mkdir /Volumes/EFI sudo mount -t msdos /dev/[EFI 分区路径] /Volumes/EFI
- 编辑 OC 文件夹下的 config.plist 配置文件
- 将 Misc -> Boot -> Timeout 值设置为非 0,以开启自动启动
- 查看 EFI 分区路径
此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK