因為想要用Xcode編譯一些東西,所以有了在Linux電腦裝MacOS虛擬機的念頭。
過去Ivon會採用Virtualbox或VMware裝虛擬機,不過對新版macOS的支援度都不太好。最近幾年Ivon改採用Github上一個很受歡迎的解決方案,那就是Dhiru Kholia維護的OSX-KVM,簡單易用。作者提供多種版本的macOS映像檔,目前支援到macOS Sequoia (15.0),不斷更新中。
OSX-KVM方案好處在於:
- 利用Linux的QEMU/KVM跑虛擬機,高效率又免費用。
- 不需要實體Mac電腦製作ISO,也能在Linux安裝macOS虛擬機。
- 虛擬機的macOS系統,除依賴硬體的iCloud Handoff功能以外,一切正常運作,可以跑Xcode和Homebrew,也能夠連接iPhone/iPad進行偵錯。
- 能夠選擇跑headless的macOS虛擬機,用SSH遠端登入編譯程式。
- 嫌圖形性能不佳的,還可以直通GPU給虛擬機加強性能。
關於法律問題,OSX-KVM其實就是虛擬機版的黑蘋果(hackintosh),作者宣稱虛擬機的「Apple-OSK」金鑰網路上到處都找得到,因此不保證合法性。
註解: 雖然OSX-KVM是開源專案,但是作者可能嫌垃圾issue太多,關閉了Github的issue功能,僅接受付費諮詢。如果你想要更開放的專案,可以考慮參與Coopydood/ultimate-macOS-KVM或者royalgraphx/DarwinKVM
1. 安裝前置依賴套件#
QEMU會模擬一部iMac Pro,搭配OpenCore引導開機,在Apple放棄支援x86架構之前應該都還能用。
跑OSX-KVM專案之前請確認硬體支援度:需要x86架構的CPU,且macOS Ventura以上的版本需要CPU支援AVX2指令集。所以你的Linux電腦需要搭載4核心以上的CPU,8GB以上的RAM,還有128GB以上的硬碟空間。
sudo apt install qemu-system qemu-system-gui uml-utilities virt-manager git \
wget libguestfs-tools p7zip-full make dmg2img tesseract-ocr \
tesseract-ocr-eng genisoimage vim net-tools screen
2. 複製OSX-KVM儲存庫#
- 複製OSX-KVM儲存庫到家目錄
cd ~
git clone --depth 1 --recursive https://github.com/kholia/OSX-KVM.git
cd OSX-KVM
- 執行下載指令稿,輸入數字選擇macOS版本。帶有
RECOMMENDED
標籤的是作者建議的穩定版本,太新的版本可能無法開機。此階段只會下載600MB的macOS Base System,用於還原安裝完整macOS。
./fetch-macOS-v2.py
- 將DMG轉成IMG:
dmg2img -i BaseSystem.dmg BaseSystem.img
- 建立一個虛擬硬碟,建議至少128GB。
qemu-img create -f qcow2 mac_hdd_ng.img 128G
3. 開始安裝macOS虛擬機#
OpenCore-Boot.sh
是QEMU的開機指令稿,用文字編輯器開啟OpenCore-Boot.sh
vim OpenCore-Boot.sh
- 視需求加大分配給虛擬機的RAM。然後修改模擬的CPU核心數,把它改成接近宿主機的數值。
ALLOCATED_RAM="8192" # MiB
CPU_SOCKETS="1"
CPU_CORES="4"
CPU_THREADS="4"
- 用
OpenCore-Boot.sh
指令稿開機,QEMU GTK視窗應該會自己跳出來。
./OpenCore-Boot.sh
點一下方向鍵移動到Base System,按下Enter
點選磁碟工具(Disk Utility),Continue。
選取剛剛建立的虛擬硬碟,點選Erase開始格式化
給硬碟取名,Format選擇
macOS Extended (Journal)
,虛擬機不要選APFS關閉磁碟工具,回到主畫面,點選
Reinstall macOS
,按Continue。接著按照螢幕指示完成安裝,下載檔案和安裝系統要2小時以上,慢慢等吧。
安裝期間可能需要反覆重開虛擬機才能順利裝完,之後會進到以下畫面。
設定好時間、語言、使用者帳號。進入桌面之後點選系統設定 → 系統更新,讓系統跑完更新,但不要進行系統大版本升級。虛擬機裡面進行macOS大版本升級很容易失敗,建議先保持在安裝當下的版本就好。
macOS虛擬機沒聲音是正常的,你可以準備一個支援macOS的USB音效卡,將其手動直通給虛擬機。
開機指令稿
OpenCore-Boot.sh
有啟用SSH通訊埠轉發,所以你可以從Linux宿主機輸入ssh localhost -p 2222
登入macOS。日後要開機請執行
OpenCore-Boot.sh
指令稿並選取macOS硬碟開機。
4. 將iPhone連接到macOS虛擬機#
安裝libimobiledevice套件,將iPhone插到Linux電腦,嘗試能否連線。
用
lsusb -t
指令列出裝置,查看電腦上的USB孔,以及載入的驅動
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/10p, 480M
|__ Port 1: Dev 20, If 0, Class=Imaging, Driver=, 480M
|__ Port 1: Dev 20, If 1, Class=Vendor Specific Class, Driver=usbfs, 480M
|__ Port 1: Dev 20, If 2, Class=Vendor Specific Class, Driver=ipheth, 480M
- 再用
lsusb
指令查看iPhone的位址,Apple製造的產品通常都是固定05ac
開頭
Bus 001 Device 020: ID 05ac:12a8 Apple, Inc. iPhone 5/5C/5S/6/SE
- 新增udev規則
sudo vim /etc/udev/rules.d/97-iphone.rules
- 填入以下內容,這樣開機後才只有QEMU能使用此裝置
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="*",GROUP="users", MODE="0660"
- 防止宿主機搶走iPhone連線,編輯usbmuxd的udev規則
sudo vim /etc/udev/rules.d/39-usbmuxd.rules
- 新增以下內容
# filename is chosen to overwrite /usr/lib/udev/rules.d/39-usbmuxd.rules
# see RULES FILES section in udev(7)
#SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", MODE="0666", TAG+="systemd"
- 重新啟動udevd服務
sudo udevadm control -R
- 編輯
OpenCore-Boot.sh
,找到args=()
這段,在末端將iOS的裝置位址加進去。vendorid
是lsusb所列出的數值前面加上0x
。
-usb -device usb-host,bus=ehci.0,vendorid=0x05ac,productid=0x12a8,guest-reset=false,id=iphone
- 啟動虛擬機,之後Mac的Finder應該就會看到iPhone。
5. 將macOS虛擬機加到Virt Manager#
(選擇性)將macOS虛擬機資訊匯入到Virt Manager,就不需要用指令稿開機了。
不過Virt Manager的XML與QEMU指令有差距,把它加入到這裡再編輯設定,可能會開不了機。
安裝完虛擬機後,將macOS關機。
修改XML,並用virt-xml工具驗證是否合法
sed "s/CHANGEME/$USER/g" macOS-libvirt-Catalina.xml > macOS.xml
virt-xml-validate macOS.xml
- 用macOS的XML建立虛擬機
virsh --connect qemu:///system define macOS.xml
- 設定目錄權限
sudo setfacl -m u:libvirt-qemu:rx /home/$USER
sudo setfacl -R -m u:libvirt-qemu:rx /home/$USER/OSX-KVM
這樣macOS就會出現在Virt Manager列表了,可以直接從這裡開機。注意macOS硬體檢查比較嚴格,在改虛擬機參數前請先閱讀作者的文件。
點Virt Manager選單列表的虛擬機 → USB重導向,就可以將iPhone接到虛擬機。
6. 將GPU直通給macOS虛擬機#
以下內容需要您對黑蘋果有點概念。
雖然QEMU/KVM技術執行虛擬機算快了,可是圖形效能低落,只能勉強編譯些程式,不能做圖形設計。條件允許的用戶可以考慮顯示卡直通(GPU Passthrough)給虛擬機強化3D性能。
顯示卡推薦AMD或Intel的,Nvidia驅動在新版本macOS幾乎不能用了。如果您的螢幕有HDMI輸出,也能順便解決虛擬機沒音效的問題。
sudo cp vfio-kvm.rules /etc/udev/rules.d/vfio-kvm.rules
sudo udevadm control --reload
sudo udevadm trigger
- 編輯
/etc/security/limits.conf
,加入以下內容:
@kvm soft memlock unlimited
@kvm hard memlock unlimited
@libvirt soft memlock unlimited
@libvirt hard memlock unlimited
- 編輯
OpenCore-Boot.sh
或用boot-passthrough.sh
,加上QEMU參數。host=00:02.0
即Intel硬體的代號,可以從Virt Manager → 新增PCI裝置觀察
-usb -device vfio-pci,host=00:02.0,multifunction=on,x-no-kvm-intx=on
接著參考Dortania’s Guide和WhateverGreen,修補OSX-KVM目錄下的
OpenCore/config.plist
,在DeviceProperties加入對應的顯示卡數值。ProperTree有提供Linux版本。修改
config.plist
後要重新生成qcow2
cd OpenCore
rm OpenCore.qcow2
sudo ./opencore-image-ng.sh --cfg config.plist --img OpenCore.qcow2
- 之後嘗試啟動虛擬機。