Как установить OS X на QEMU и не схватить Kernel PANIC

от автора

Внимание, этот гайд предназначен для macOS хостов. Если у вас другой хост, некоторые настройки придётся переделывать!

Введение

В этой статье, я буду использовать OpenCore (сокращённо OC), в качестве основного загрузчика, и EDK II в качестве прошивки.

Для тех кто не знаком с OC советую почитать:

Также, здесь описана только установка версий 10.7-10.8, но в принципе эти инструкции довольно легко адаптировать под более новые версии.

Подготовка

Для папки с виртуальной машиной я обычно использую вот такую структуру:

🗂️ Имя виртуальной машины 📖 Firmware.rom(файл прошивки - edk2-x86_64-code.fd) HD.qcow2(образ жёсткого диска) 📀 Installer.dmg(образ установщика) ⚙️ run(скрипт запуска) Settings.img(образ настроек NVRAM - edk2-i386-code.fd)

Сначала надо скачать образ установщика (советую вам использовать download manager, так как образ довольно увесистый), а затем скопировать .fd файлы, которые лежат в /opt/homebrew/share/qemu если вы устанавливали QEMU через Homebrew или в /usr/local/share если собирали его сами.

Установщик который вы скачали имеет следующую структуру:

🗂️ InstallMacOSX.dmg 🗜️ InstallMacOSX.pkg(архив в формате xar) 📄 Distribution(сценарий установки) 📦 InstallMacOSX.pkg(вложенный пакет) 🧾 Bom(метаданные) 📀 InstallESD.dmg(загрузочный образ) PackageInfo 🗜️ Payload(остальные устоновочные данные) ⚙️ Scripts(скрипты пакета) 📁 Resources(ресурсы пакета)

Скопируйте загрузочный образ в папку виртуальной машины.

Установка OC

Теперь, когда мы подготовили основные компоненты, необходимо сделать образ ЖД и установить туда OpenCore.

Сначала скачиваем последний релиз OpenCore (я использовал 1.0.4).

Затем нам понадобятся необходимые кекты: Lilu и VirtualSMC (остальные можно скачать по желанию). Я использовал релизы 1.7.0 для Lilu и 1.3.6 для VirtualSMC.

Как вы возможно заметили, все компоненты OC поставляются в виде двух версий, Release и Debug

Версия Debug отличается тем что там поддерживается логирования загрузки и выводится отладочная информация. Я советую именно её, по крайней мере до тех пор пока вы не отладите свою конфигурацию, и не убедитесь что ваша виртуальная машина работает идеально. Я же буду использовать Release версию.

Также нам понадобится инструмент GenSMBIOS для генерирования серийных номеров и других полей. В принципе можно обойтись и без него, но это будет сложнее.

Стандартная структура OC такая:

🗂️ OpenCore-x.x.x-СБОРКА 📂 Docs   📄 Changelog.md(изменения новой версии) 📄 Configuration.pdf(документация параметров OpenCore)   Sample.plist(пример конфигурации)   📂 IA32(32-битный загрузчик) 📁 EFI   📂 Utilities(полезные программы) 📂 X64(64-битный загрузчик) 📁 EFI

Так как нам нужна 64-битная архитектура, копируем папку EFI из каталога X64 в любое удобное место.

Структура папки EFI примерно такова:

🗂️ EFI 📂 BOOT ⚙️ BOOTx64.efi(загрузчик) 📂 OC(настройки)   📁 ACPI(ACPI таблицы) 📁 Drivers(драйвера) 📁 Kexts(драйвера для OS X) OpenCore.efi(главный исполняемы файл загрузчика) 📂 Resources(ресурсы OpenCanopy) 📁 Audio 📁 Font 📁 Image 📁 Label 📁 Tools(дополнительные программы)

Настройка OC

Разумеется из этих инструментов на понадобится далеко не всё. Можно смело удалять папки ACPI и Resources, а также файлы .contentVisibility и .contentFlavour из папки OC. Также зайдите в папку Drivers, и оставьте только следующие драйвера:

  • OpenHfsPlus.efi

  • OpenPartitionDxe.efi

  • OpenRuntime.efi

  • ResetNvramEntry.efi

Затем зайдите в папку Tools и удалите всё кроме файла OpenShell.efi.

Теперь перейдём к кекстам. Распакуйте архивы Lilu и VirtualSMC которые скачали. Извлеките файлы Lilu.kext и VirtualSMC.kext, и положите в папку Kexts.

В итоге должна получится следующая структура (после - обозначены бывшие имена фалов, не забудьте переименовать!):

🗂️ EFI 📂 BOOT ⚙️ BOOTx64.efi(загрузчик) .contentVisibility(видимость раздела)   📂 OC(настройки) 📂 Drivers(драйвера) 🔧 Filesystems.efi(драйвер для HFS - OpenHfsPlus.efi) 🔧 Menu additions.efi(опция сброса NVRAM - ResetNvramEntry.efi)   🔧 Partition tables.efi(драйвер для схем разделов - OpenPartitionDxe.efi) 🔧 Runtime.efi(главный двигатель OpenCore - OpenRuntime.efi) 📂 Kexts(драйвера для OS X) 🧩 Lilu.kext(runtime для всех остальных кекстов) 🧩 Virtual SMC.kext(эмуляция SMC - VirtualSMC.kext) OpenCore.efi(главный исполняемы файл загрузчика) 📂 Tools(дополнительные программы) Shell.efi(программа командной строки - OpenShell.efi)

Таким образом, основная подготовка OpenCore закончена!

Генерация SMBIOS

Для начала, нам понадобится SMBIOS данные, чтобы OS X корректно распознавала аппаратное обеспечение. Для этого откройте папку скачанного GenSMBIOS в терминале, и выполните следующую команду для запуска:

chmod +x GenSMBIOS.command ./GenSMBIOS.command

Выберете инструмент 3 и введите одну из следующих моделей (идентификатор указан в моноширным шрифтом):

  • iMac 2011, подходит для OS X Lion iMac12,2

  • iMac 2012, подходит для OS X Mountain Lion iMac13,2

Запишите 4 параметра:

  1. Board serial

  2. Apple ROM

  3. Serial

  4. SmUUID

Как закодировать Apple ROM в base64?
echo -n "Apple ROM" | xxd -r -p | base64

Просто поставьте свой Apple ROM в echo.

Создание config.plist

Теперь осталось лишь сделать правильный конфиг (config.plist).

Вот код config.plist (вы можете добавить или изменить что-то, либо использовать как есть):

<!-- config.plist -->  <plist> <dict> <key>Booter</key> <dict> <key>Quirks</key> <dict> <key>EnableSafeModeSlide</key> <true/> </dict> </dict>  <key>UEFI</key> <dict> <key>ConnectDrivers</key> <true/>  <key>Drivers</key> <array> <dict> <key>Path</key> <string>Runtime.efi</string> <key>Enabled</key> <true/> </dict>  <dict> <key>Path</key> <string>Partition tables.efi</string> <key>Enabled</key> <true/> </dict> <dict> <key>Path</key> <string>Filesystems.efi</string> <key>Enabled</key> <true/> </dict>  <dict> <key>Path</key> <string>Menu additions.efi</string> <key>Enabled</key> <true/> </dict> </array>  <key>Input</key> <dict> <key>KeySupport</key> <true/> </dict>  <key>Quirks</key> <dict> <key>RequestBootVarRouting</key> <true/> </dict> </dict>  <key>Misc</key> <dict> <key>Entries</key> <array/>  <key>Boot</key> <dict> <key>ConsoleAttributes</key> <integer>15</integer> <key>PickerAttributes</key> <integer>256</integer>  <key>PollAppleHotKeys</key> <true/>  <key>ShowPicker</key> <true/> <key>Timeout</key> <integer>5</integer> </dict>  <key>Security</key> <dict> <key>AllowSetDefault</key> <true/>  <key>DmgLoading</key> <string>Any</string> <key>ScanPolicy</key> <integer>0</integer>  <key>SecureBootModel</key> <string>Disabled</string>  <key>Vault</key> <string>Optional</string> </dict>  <key>Debug</key> <dict> <key>ApplePanic</key> <true/> <key>Target</key> <integer>73</integer> <key>DisplayLevel</key> <integer>2147483650</integer> </dict>  <key>Tools</key> <array> <dict> <key>Name</key> <string>UEFI Shell</string> <key>Path</key> <string>Shell.efi</string>  <key>Enabled</key> <true/> </dict> </array> </dict>  <key>NVRAM</key> <dict> <key>Add</key> <dict> <key>7C436110-AB2A-4BBB-A880-FE41995C9F82</key> <dict> <key>boot-args</key> <string></string> <key>run-efi-updater</key> <string>No</string> </dict> </dict>  <key>Delete</key> <dict> <key>7C436110-AB2A-4BBB-A880-FE41995C9F82</key> <array> <string>boot-args</string> </array> </dict>  <key>WriteFlash</key> <true/> </dict>  <key>Kernel</key> <dict> <key>Add</key> <array> <dict> <key>BundlePath</key> <string>Lilu.kext</string> <key>ExecutablePath</key> <string>Contents/MacOS/Lilu</string> <key>PlistPath</key> <string>Contents/Info.plist</string>  <key>Arch</key> <string>x86_64</string>  <key>Enabled</key> <true/> </dict> <dict> <key>BundlePath</key> <string>Virtual SMC.kext</string> <key>ExecutablePath</key> <string>Contents/MacOS/VirtualSMC</string> <key>PlistPath</key> <string>Contents/Info.plist</string>  <key>Arch</key> <string>x86_64</string>  <key>Enabled</key> <true/> </dict> </array>  <key>Emulate</key> <dict> <key>DummyPowerManagement</key> <true/> </dict>  <key>Scheme</key> <dict> <key>KernelArch</key> <string>x86_64</string> <key>FuzzyMatch</key> <true/> </dict> </dict>  <key>PlatformInfo</key> <dict> <key>Automatic</key> <true/>  <key>Generic</key> <dict> <key>MLB</key> <string>Board serial</string> <key>ROM</key> <data>Apple ROM (base64 encoded)</data>  <key>SystemProductName</key> <string>Type</string> <key>SystemSerialNumber</key> <string>Serial</string> <key>SystemUUID</key> <string>SmUUID</string> </dict>  <key>UpdateDataHub</key> <true/> <key>UpdateSMBIOS</key> <true/> </dict> </dict> </plist>
Нужны пояснения?
<!-- config.plist -->  <plist> <dict> <key>Booter</key> <dict> <key>Quirks</key> <dict> <!-- Чтобы работал Safe mode --> <key>EnableSafeModeSlide</key> <true/> </dict> </dict>  <key>UEFI</key> <dict> <!-- Чтобы можно было загрузить драйвера --> <key>ConnectDrivers</key> <true/>  <key>Drivers</key> <array> <dict> <key>Path</key> <string>Runtime.efi</string> <key>Enabled</key> <true/> </dict>  <dict> <key>Path</key> <string>Partition tables.efi</string> <key>Enabled</key> <true/> </dict> <dict> <key>Path</key> <string>Filesystems.efi</string> <key>Enabled</key> <true/> </dict>  <dict> <key>Path</key> <string>Menu additions.efi</string> <key>Enabled</key> <true/> </dict> </array>  <key>Input</key> <dict> <!-- Чтобы в меню работала клавиатура --> <key>KeySupport</key> <true/> </dict>  <key>Quirks</key> <dict> <!-- Чтобы работал выбор загрузочного диска из OS X --> <key>RequestBootVarRouting</key> <true/> </dict> </dict>  <key>Misc</key> <dict>         <!-- Фикс для бага с .contentVisibility --> <key>Entries</key> <array/>  <key>Boot</key> <dict> <!-- Стиль XNU, яркий белый на чёрном --> <key>ConsoleAttributes</key> <integer>15</integer> <!-- Restart идёт до Shut down --> <key>PickerAttributes</key> <integer>256</integer>  <!-- Чтобы работали горячие клавишы (например ⌘V) --> <key>PollAppleHotKeys</key> <true/>  <!-- Чтобы показывалось меню загрузки --> <key>ShowPicker</key> <true/> <!-- Таймаут меню (в секундах) --> <key>Timeout</key> <integer>5</integer> </dict>  <key>Security</key> <dict> <!-- Чтобы работала возможность поставить запись по умолчанию из меню (⌃⏎) --> <key>AllowSetDefault</key> <true/>  <!-- Возможность загружаться с неподписанных DMG --> <key>DmgLoading</key> <string>Any</string> <!-- Чтобы показывались ВСЕ записи --> <key>ScanPolicy</key> <integer>0</integer>  <!-- Отключение Secure boot (10.8 его не поддерживает) --> <key>SecureBootModel</key> <string>Disabled</string>  <!-- Фикс для ошибки "OCS: No vault provided" --> <key>Vault</key> <string>Optional</string> </dict>  <!-- Опции для отладки, игнорируются в Release сборке --> <key>Debug</key> <dict> <!-- Сохранение паники в лог --> <key>ApplePanic</key> <true/> <!-- Логирование, вывод в серийную консоль и сохранение в файл --> <key>Target</key> <integer>73</integer> <!-- Логирование предупреждений и ошибок --> <key>DisplayLevel</key> <integer>2147483650</integer> </dict>  <key>Tools</key> <array> <dict> <key>Name</key> <string>UEFI Shell</string> <key>Path</key> <string>Shell.efi</string>  <key>Enabled</key> <true/> </dict> </array> </dict>  <key>NVRAM</key> <dict> <key>Add</key> <dict> <key>7C436110-AB2A-4BBB-A880-FE41995C9F82</key> <dict> <!-- Можно добавить -v для отладки --> <key>boot-args</key> <string></string> <!-- Чтобы обновление не попыталось перезаписать прошивку --> <key>run-efi-updater</key> <string>No</string> </dict> </dict>  <!-- Решение конфликта NVRAM --> <key>Delete</key> <dict> <key>7C436110-AB2A-4BBB-A880-FE41995C9F82</key> <array> <string>boot-args</string> </array> </dict>  <!-- Чтобы работал выбор загрузочного диска из OS X --> <key>WriteFlash</key> <true/> </dict>  <key>Kernel</key> <dict> <key>Add</key> <array> <dict> <key>BundlePath</key> <string>Lilu.kext</string> <key>ExecutablePath</key> <string>Contents/MacOS/Lilu</string> <key>PlistPath</key> <string>Contents/Info.plist</string>  <key>Arch</key> <string>x86_64</string>  <key>Enabled</key> <true/> </dict> <dict> <key>BundlePath</key> <string>Virtual SMC.kext</string> <key>ExecutablePath</key> <string>Contents/MacOS/VirtualSMC</string> <key>PlistPath</key> <string>Contents/Info.plist</string>  <key>Arch</key> <string>x86_64</string>  <key>Enabled</key> <true/> </dict> </array>  <!-- Фикс для паники ядра на "AppleIntelCPUPowerManagment" --> <key>Emulate</key> <dict> <key>DummyPowerManagement</key> <true/> </dict>  <key>Scheme</key> <dict> <key>KernelArch</key> <string>x86_64</string> <!-- Нужен для старых версий --> <key>FuzzyMatch</key> <true/> </dict> </dict>  <key>PlatformInfo</key> <dict> <!-- Нужен для того чтобы не пришлось указывать все параметры --> <key>Automatic</key> <true/>  <key>Generic</key> <dict> <!-- Нужны для iCloud --> <key>MLB</key> <string>Board serial</string> <key>ROM</key> <data>Apple ROM (base64 encoded)</data>  <!-- Чтобы OS X корректно распознавала АО --> <key>SystemProductName</key> <string>Type</string> <key>SystemSerialNumber</key> <string>Serial</string> <key>SystemUUID</key> <string>SmUUID</string> </dict>  <!-- Чтобы настройки SMBIOS применялись --> <key>UpdateDataHub</key> <true/> <key>UpdateSMBIOS</key> <true/> </dict> </dict> </plist>

НЕ ЗАБУДЬТЕ ПОДСТАВИТЬ КОРРЕКТНЫЕ ЗНАЧЕНИЯ SMBIOS В КОНФИГ!

Подготовка жёсткого диска

Сначала необходимо создать образ жёсткого диска. Желательно сделать образ размером в половину вашего реального жёсткого диска, но вы можете выбрать любой размер.

hdiutil create -size размерG HD.dmg hdiutil attach -nomount HD.dmg

Далее посмотрите на вывод hdiutil чтобы узнать куда он примонтировал диск. В дальнейших командах, diskX, не забудьте заменить на реальную цифру!

diskutil eraseDisk JHFS+ "HD" diskX diskutil mount diskXs1 diskutil mount diskXs2

Скопируйте EFI папку в /Volumes/EFI, а затем выполните последующие команды.

dot_clean {/Volumes/EFI,/Volumes/HD} rm -rf {/Volumes/EFI,/Volumes/HD}/.* hdiutil detach diskX mv HD.dmg HD.img qemu-img convert HD.img HD.qcow2 -O qcow2 rm HD.img

ВНИМАНИЕ! УБЕДИТЕСЬ ЧТО ЖЁСТКИЙ ДИСК ВАШЕГО КОМПЬЮТЕРА НЕ НАЗЫВАЕТСЯ HD, ИНАЧЕ ВЫ МОЖЕТЕ СТЕРЕТЬ НЕКОТОРЫЕ ДАННЫЕ НА СВОЁМ КОМПЬЮТЕРЕ!

Создание run

Теперь, когда жёсткий диск и образ установщика подготовлены осталось лишь написать скрипт запуска.

Однако сначала определим какая модель процессора соответствует выбранной модели ПК:

  • iMac 2011 → SandyBridge

  • iMac 2012 → IvyBridge

Вот код run (вы можете добавить или изменить что-то, либо использовать как есть):

#!/bin/zsh  sudo qemu-system-x86_64 \ -name "OS X Версия" \ -machine q35 \ -full-screen \ \ -drive if=pflash,file="Firmware.rom",readonly=true \ -drive if=pflash,file="Settings.img" \ \ -hda "HD.qcow2" \ -cdrom "Installer.dmg" \ \ -cpu Процессор,+sse4.1 \ -m оперативная памятьG \ -smp сумма ядер и потоков,cores=ядра,threads=потоки \ \ -device ich9-usb-uhci1 \ -device usb-mouse \ -device usb-kbd \ \ -device usb-audio,audiodev=audio \ -device e1000,netdev=network \ \ -audiodev id=audio,driver=coreaudio \ -netdev id=network,type=vmnet-shared \ \ -accel hvf/tcg (в зависимости от того что поддерживается)
Нужны пояснения?
#!/bin/zsh  # sudo нужно для корректной работы VMNet sudo qemu-system-x86_64 \ # Имя виртуальной машины которое будет отображаться над окном -name "OS X Версия" \ # Современный чипсет -machine q35 \ # Во весь экран, для поноты ощущений -full-screen \ \ # Прошивка и NVRAM -drive if=pflash,file="Firmware.rom",readonly=true \ -drive if=pflash,file="Settings.img" \ \ # Жёсткий диск и DVD установщика -hda "HD.img" \ -cdrom "Installer.dmg" \ \ # sse4.1 необходим для OS X -cpu Penryn,+sse4.1 \ # Оперативная память и количество ядер/потоков -m оперативная памятьG \ -smp сумма ядер и потоков,cores=ядра,threads=потоки \ \ # UHCI нужен чтобы работало USB Audio, а XHCI не работает в OS X -device ich9-usb-uhci1 \ # USB мышка и клавиатура -device usb-mouse \ -device usb-kbd \ \ # USB аудио (единственная аудиокарта работающая в OS X без драйверов) -device usb-audio,audiodev=audio \ # Сетевая карта Gigabit Ethernet, работает нативно -device e1000,netdev=network \ \ # Подключение аудио и сети к хосту, VMNet даёт реальный MAC и IP адреса -audiodev id=audio,driver=coreaudio \ -netdev id=network,type=vmnet-shared \ \ # HVF это аппаратное ускорение, но если он недоступен, запаситесь терпение и включите TCG -accel hvf/tcg (в зависимости от того что поддерживается)

НЕ ЗАБУДЬТЕ ПОДСТАВИТЬ КОРРЕКТНЫЕ ЗНАЧЕНИЯ В КОНФИГ!

БОНУС

Если у вас получилось установить OS X по этой статье, то вы наверняка успели столкнуться со следующей ошибкой: TLS handshake failed (или если вы не лезли глубоко в систему: Safari cannot open this page).

Это происходит из-за того что со времён тех версий OS X которые мы с вами ставили прошло много времени, и протоколы шифрования (вроде TLS 1.1) успели поменяться на более новые (как TLS 1.3), а поддержка старых протоколов была депрецирована.

Также, даже если вам удасться решить эту проблемы в столкнётесь с проблемой сертификатов, когда браузер будет утверждать что сайт не безопасен (что происходит из-за устаревшей базы сертификатов). Это уже не такая помеха как предыдущая ошибка, но также может раздражать.

Обе эти проблемы решает инструмент Legacy Mac Proxy. Он устанавливается из .pkg установщика и в конце говорит какие шаги сделать в настройках чтобы его активировать.

Немного подробностей

Legacy Mac Proxy это MiTM (main in the middle) сервер основанный на локальной версии прокси под названием Squid. Он делает сразу две вещи:

  1. Перехватывает HTTPS соединения, дешифрует современные протоколы, а потом шифрует их обратно с помощью более старого алгоритма (зависит от версии OS X)

  2. Добавляет свой коренной сертификат в Keychain Access и устанавливает к нему доверие, что позволяет избежать проблемы с устаревшей базой сертификатов

Также, прошу заметить, что некоторые браузеры (например FireFox) недоверяют системным сертификатам, потому потребуется экспортировать сертификат Squid из Keychain Access в .cer формат, а затем импортировать его в браузер и установить к нему доверие вручную.

Заключение

Вот и всё, осталось только запустить run. Однако, необходимо помнить что нужно запускать его из той же папки где находится он сам, иначе будут ошибки. Открепить ВМ от терминала можно добавив & disown к ./run.

Ну а если вы хотите настроить разрешение экрана виртуальной машины, можете нажать F2 при запуске UEFI, зайти в Device Manager → OVMF Platform Configuration, изменить там разрешение, и нажать F10 чтобы сохранить изменения. Не забудьте перезагрузиться!

Также помните что форматировать диск в Disk Utility нельзя, во первых потому что он полностью готов к установке, а во вторых потому что там находится OpenCore.

P. S. Если у вас возникнут проблемы или вопросы, пишите в комментарии!


ссылка на оригинал статьи https://habr.com/ru/articles/918550/