macOS: current Lilu/VirtualSMC/WhateverGreen/RestrictEvents, no isa-applesmc
The OSX-KVM ESP ships Lilu 1.6.8 / VirtualSMC 1.3.3 / WhateverGreen 1.6.7,
which disable themselves on macOS 26; Apple's SMC driver then runs on QEMU's
isa-applesmc stub and the restart path panics (SMCWDT smcWriteKey
kSMCBadCommand → nested panic after MACH Reboot). Overlay pinned current
releases (upstream.json opencore.kexts) and drop isa-applesmc: with the stub
present VirtualSMC steps aside ("multiple devices present"); alone it carries
the OSK and reboots work (PE restart test: 10 s, clean). RestrictEvents with
revpatch=memtab silences MacPro7,1's "Memory Modules Misconfigured".
- makeOpenCore: kext overlay + Kernel.Add entries for overlaid kexts,
--memory-mb (4 DIMMs), bootArgs default revpatch=memtab
- qemu.nix: deviceArgsFor { appleSmc } (default false); cli: --applesmc for
images built before this change
- vm-driver: reboot-death detection (reset 60 s after a guest reboot request
that never comes back), panics wait for XNU's own auto-reboot, debug dir
works across nixbld users
- generalize: QEMU USB keyboard declared ANSI (no Keyboard Setup Assistant)
- README: architecture, reliability handling, debugging
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsESshRCoBoUVWV9qKURUF
This commit is contained in:
parent
8dc8f4265d
commit
22daf7720c
8 changed files with 97 additions and 15 deletions
5
cli.nix
5
cli.nix
|
|
@ -33,7 +33,8 @@ pkgs.writeShellScriptBin "vmix" ''
|
||||||
echo " --to-remote-disk SSH:DEV Stream to remote disk via SSH and expand partitions"
|
echo " --to-remote-disk SSH:DEV Stream to remote disk via SSH and expand partitions"
|
||||||
echo " e.g. root@10.10.10.100:/dev/sda"
|
echo " e.g. root@10.10.10.100:/dev/sda"
|
||||||
echo " --ahci Use AHCI storage for vmix run (for laptop images)"
|
echo " --ahci Use AHCI storage for vmix run (for laptop images)"
|
||||||
echo " --macos macOS image for vmix run (OpenCore/AppleSMC flags, AHCI)"
|
echo " --macos macOS image for vmix run (OpenCore/VirtualSMC flags, AHCI)"
|
||||||
|
echo " --applesmc with --macos: add QEMU's isa-applesmc (images built before 2026-09-09)"
|
||||||
echo " --vnc DISPLAY VNC instead of SDL for vmix run, e.g. :10 (port 5910) or 0.0.0.0:10"
|
echo " --vnc DISPLAY VNC instead of SDL for vmix run, e.g. :10 (port 5910) or 0.0.0.0:10"
|
||||||
echo " --mac ADDR NIC MAC for vmix run (macOS: read from the image's ESP by default)"
|
echo " --mac ADDR NIC MAC for vmix run (macOS: read from the image's ESP by default)"
|
||||||
echo " -y, --yes Skip disk write confirmation"
|
echo " -y, --yes Skip disk write confirmation"
|
||||||
|
|
@ -100,6 +101,7 @@ pkgs.writeShellScriptBin "vmix" ''
|
||||||
--smp) RUN_SMP="$2"; shift 2 ;;
|
--smp) RUN_SMP="$2"; shift 2 ;;
|
||||||
--ahci) RUN_AHCI=true; shift ;;
|
--ahci) RUN_AHCI=true; shift ;;
|
||||||
--macos) RUN_MACOS=true; shift ;;
|
--macos) RUN_MACOS=true; shift ;;
|
||||||
|
--applesmc) RUN_APPLESMC=true; shift ;;
|
||||||
--vnc) RUN_VNC="$2"; shift 2 ;;
|
--vnc) RUN_VNC="$2"; shift 2 ;;
|
||||||
--mac) RUN_MAC="$2"; shift 2 ;;
|
--mac) RUN_MAC="$2"; shift 2 ;;
|
||||||
*) echo "Unknown option: $1"; exit 1 ;;
|
*) echo "Unknown option: $1"; exit 1 ;;
|
||||||
|
|
@ -138,6 +140,7 @@ pkgs.writeShellScriptBin "vmix" ''
|
||||||
exec ${pkgs.qemu}/bin/qemu-system-x86_64 \
|
exec ${pkgs.qemu}/bin/qemu-system-x86_64 \
|
||||||
$VMIX_DISPLAY \
|
$VMIX_DISPLAY \
|
||||||
${macosQemu.deviceArgs} ${macosQemu.vgaArgs} \
|
${macosQemu.deviceArgs} ${macosQemu.vgaArgs} \
|
||||||
|
$([[ "$RUN_APPLESMC" == true ]] && echo '-device isa-applesmc,osk="${macosQemu.osk}"') \
|
||||||
-accel kvm \
|
-accel kvm \
|
||||||
-machine type=q35 \
|
-machine type=q35 \
|
||||||
-cpu ${macosQemu.defaultCpu} \
|
-cpu ${macosQemu.defaultCpu} \
|
||||||
|
|
|
||||||
|
|
@ -98,3 +98,14 @@ AppleSMC with the OSK, XHCI keyboard/tablet, AHCI disks, VMware SVGA,
|
||||||
virtio-net pinned to `PciRoot(0x0)/Pci(0x12,0x0)` so OpenCore marks it built-in
|
virtio-net pinned to `PciRoot(0x0)/Pci(0x12,0x0)` so OpenCore marks it built-in
|
||||||
(en0, required for Apple ID / iMessage). SMBIOS `MacPro7,1` with four DIMMs
|
(en0, required for Apple ID / iMessage). SMBIOS `MacPro7,1` with four DIMMs
|
||||||
described (avoids the "Memory Modules Misconfigured" warning).
|
described (avoids the "Memory Modules Misconfigured" warning).
|
||||||
|
|
||||||
|
OpenCore comes from OSX-KVM's proven ESP, with Lilu / VirtualSMC /
|
||||||
|
WhateverGreen replaced by current releases (`upstream.json` → `opencore.kexts`):
|
||||||
|
the versions OSX-KVM ships disable themselves on macOS 26, and without
|
||||||
|
VirtualSMC the guest's restart path panics on QEMU's SMC stub
|
||||||
|
(`SMCWDT smcWriteKey kSMCBadCommand`, nested panic after `MACH Reboot`).
|
||||||
|
For the same reason QEMU's `isa-applesmc` is not used any more: its presence
|
||||||
|
makes VirtualSMC step aside ("multiple devices present"); VirtualSMC carries
|
||||||
|
the OSK itself. Images built before this change still need the stub:
|
||||||
|
`vmix run --macos --applesmc`. RestrictEvents (`revpatch=memtab`) silences
|
||||||
|
MacPro7,1's "Memory Modules Misconfigured" at login.
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
cpu ? qemu.defaultCpu,
|
cpu ? qemu.defaultCpu,
|
||||||
model ? "MacPro7,1", # SMBIOS model; must be supported by the installed macOS
|
model ? "MacPro7,1", # SMBIOS model; must be supported by the installed macOS
|
||||||
seed ? name, # MAC address + SystemUUID are derived from this
|
seed ? name, # MAC address + SystemUUID are derived from this
|
||||||
bootArgs ? "keepsyms=1",
|
bootArgs ? "keepsyms=1 revpatch=memtab",
|
||||||
vncDisplay ? null, # e.g. ":10" to watch the install on port 5910
|
vncDisplay ? null, # e.g. ":10" to watch the install on port 5910
|
||||||
timeout ? 4 * 3600, # seconds for the whole install
|
timeout ? 4 * 3600, # seconds for the whole install
|
||||||
extraOpenCoreConfig ? {}, # merged into config.plist
|
extraOpenCoreConfig ? {}, # merged into config.plist
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
uuid,
|
uuid,
|
||||||
serial ? null,
|
serial ? null,
|
||||||
mlb ? null,
|
mlb ? null,
|
||||||
bootArgs ? "keepsyms=1",
|
bootArgs ? "keepsyms=1 revpatch=memtab",
|
||||||
resolution ? "1024x768",
|
resolution ? "1024x768",
|
||||||
showPicker ? true,
|
showPicker ? true,
|
||||||
pickerTimeout ? 2,
|
pickerTimeout ? 2,
|
||||||
|
|
@ -22,6 +22,12 @@
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
ocImage = pkgs.fetchurl { inherit (upstream.opencore.image) url sha256; name = "OSX-KVM-OpenCore.qcow2"; };
|
ocImage = pkgs.fetchurl { inherit (upstream.opencore.image) url sha256; name = "OSX-KVM-OpenCore.qcow2"; };
|
||||||
|
# OSX-KVM's ESP ships Lilu 1.6.8 / VirtualSMC 1.3.3 / WhateverGreen 1.6.7, which
|
||||||
|
# disable themselves on macOS 26 ("unsupported operating system"); without
|
||||||
|
# VirtualSMC, macOS' restart path panics on QEMU's SMC stub. Overlay the
|
||||||
|
# current releases (upstream.opencore.kexts, pinned).
|
||||||
|
kextZips = lib.mapAttrsToList (n: k: { name = n; zip = pkgs.fetchurl { inherit (k) url hash; }; })
|
||||||
|
(upstream.opencore.kexts or {});
|
||||||
in
|
in
|
||||||
pkgs.runCommand "${name}-esp" {
|
pkgs.runCommand "${name}-esp" {
|
||||||
nativeBuildInputs = with pkgs; [ _7zz python3 mtools dosfstools gptfdisk jq macserial ];
|
nativeBuildInputs = with pkgs; [ _7zz python3 mtools dosfstools gptfdisk jq macserial ];
|
||||||
|
|
@ -45,13 +51,23 @@ pkgs.runCommand "${name}-esp" {
|
||||||
mkdir -p $out/EFI/vmix
|
mkdir -p $out/EFI/vmix
|
||||||
cp -r esp/EFI/BOOT esp/EFI/OC $out/EFI/
|
cp -r esp/EFI/BOOT esp/EFI/OC $out/EFI/
|
||||||
chmod -R u+w $out/EFI
|
chmod -R u+w $out/EFI
|
||||||
|
${lib.concatMapStringsSep "\n" (k: ''
|
||||||
|
echo "=== vmix: updating ${k.name}.kext from ${k.zip.name} ==="
|
||||||
|
rm -rf kext-${k.name}; mkdir kext-${k.name}
|
||||||
|
${pkgs.unzip}/bin/unzip -q -o ${k.zip} -d kext-${k.name}
|
||||||
|
K=$(find kext-${k.name} -type d -name "${k.name}.kext" | head -1)
|
||||||
|
[ -n "$K" ] || { echo "${k.name}.kext not found in ${k.zip.name}"; exit 1; }
|
||||||
|
rm -rf "$out/EFI/OC/Kexts/${k.name}.kext"
|
||||||
|
cp -r "$K" "$out/EFI/OC/Kexts/${k.name}.kext"
|
||||||
|
grep -A1 CFBundleVersion "$out/EFI/OC/Kexts/${k.name}.kext/Contents/Info.plist" | tail -1
|
||||||
|
'') kextZips}
|
||||||
# hide OpenCore's own launcher from its picker (otherwise it is the default entry and loops)
|
# hide OpenCore's own launcher from its picker (otherwise it is the default entry and loops)
|
||||||
echo -n Disabled > $out/EFI/BOOT/.contentVisibility
|
echo -n Disabled > $out/EFI/BOOT/.contentVisibility
|
||||||
python3 ${./oc-config.py} --base esp/EFI/OC/config.plist --esp esp --out $out/EFI/OC/config.plist \
|
python3 ${./oc-config.py} --base esp/EFI/OC/config.plist --esp esp --out $out/EFI/OC/config.plist \
|
||||||
--model "${model}" --serial "$SERIAL" --mlb "$MLB" --uuid "${uuid}" --mac "${mac}" \
|
--model "${model}" --serial "$SERIAL" --mlb "$MLB" --uuid "${uuid}" --mac "${mac}" \
|
||||||
--nic-path "${qemu.nicDevicePath}" --boot-args "${bootArgs}" --resolution "${resolution}" \
|
--nic-path "${qemu.nicDevicePath}" --boot-args "${bootArgs}" --resolution "${resolution}" \
|
||||||
--show-picker "${lib.boolToString showPicker}" --timeout ${toString pickerTimeout} \
|
--show-picker "${lib.boolToString showPicker}" --timeout ${toString pickerTimeout} \
|
||||||
--extra-json ${lib.escapeShellArg (builtins.toJSON extraConfig)} --memory-mb ${toString memSize}
|
--extra-json ${lib.escapeShellArg (builtins.toJSON extraConfig)} --memory-mb ${toString memSize} --add-kexts ${lib.concatStringsSep "," (map (k: k.name) kextZips)}
|
||||||
ocvalidate $out/EFI/OC/config.plist || echo "vmix: ocvalidate reported issues (OpenCore version may differ from validator), continuing"
|
ocvalidate $out/EFI/OC/config.plist || echo "vmix: ocvalidate reported issues (OpenCore version may differ from validator), continuing"
|
||||||
|
|
||||||
jq -n --arg model "${model}" --arg serial "$SERIAL" --arg mlb "$MLB" --arg uuid "${uuid}" --arg mac "${mac}" \
|
jq -n --arg model "${model}" --arg serial "$SERIAL" --arg mlb "$MLB" --arg uuid "${uuid}" --arg mac "${mac}" \
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ def main():
|
||||||
p.add_argument('--timeout', type=int, default=2)
|
p.add_argument('--timeout', type=int, default=2)
|
||||||
p.add_argument('--extra-json', default='{}')
|
p.add_argument('--extra-json', default='{}')
|
||||||
p.add_argument('--memory-mb', type=int, default=8192, help='VM RAM, described as 4 DIMMs')
|
p.add_argument('--memory-mb', type=int, default=8192, help='VM RAM, described as 4 DIMMs')
|
||||||
|
p.add_argument('--add-kexts', default='', help='comma-separated kext names (without .kext) that need a Kernel.Add entry')
|
||||||
a = p.parse_args()
|
a = p.parse_args()
|
||||||
|
|
||||||
with open(a.base, 'rb') as f:
|
with open(a.base, 'rb') as f:
|
||||||
|
|
@ -85,6 +86,18 @@ def main():
|
||||||
cfg['Misc']['Boot']['Timeout'] = a.timeout
|
cfg['Misc']['Boot']['Timeout'] = a.timeout
|
||||||
cfg['Misc']['Boot']['HideAuxiliary'] = True
|
cfg['Misc']['Boot']['HideAuxiliary'] = True
|
||||||
cfg['Misc']['Security']['ScanPolicy'] = 0
|
cfg['Misc']['Security']['ScanPolicy'] = 0
|
||||||
|
# kexts overlaid into the ESP that the OSX-KVM config does not list yet
|
||||||
|
# (RestrictEvents: silences MacPro7,1's "Memory Modules Misconfigured", revpatch=memtab)
|
||||||
|
listed = {k['BundlePath'] for k in cfg['Kernel']['Add']}
|
||||||
|
for kext in [k + '.kext' for k in a.add_kexts.split(',') if k]:
|
||||||
|
if kext not in listed:
|
||||||
|
name = kext[:-5]
|
||||||
|
cfg['Kernel']['Add'].append({
|
||||||
|
'Arch': 'Any', 'BundlePath': kext, 'Comment': f'{name} (vmix)', 'Enabled': True,
|
||||||
|
'ExecutablePath': f'Contents/MacOS/{name}', 'MaxKernel': '', 'MinKernel': '',
|
||||||
|
'PlistPath': 'Contents/Info.plist'})
|
||||||
|
print('Kernel.Add +', kext)
|
||||||
|
|
||||||
# MacPro7,1 firmware expects DIMMs in pairs (>= 4); with QEMU's single SMBIOS
|
# MacPro7,1 firmware expects DIMMs in pairs (>= 4); with QEMU's single SMBIOS
|
||||||
# module macOS shows "Memory Modules Misconfigured" at every login. Describe
|
# module macOS shows "Memory Modules Misconfigured" at every login. Describe
|
||||||
# the VM's RAM as four DDR4 modules instead.
|
# the VM's RAM as four DDR4 modules instead.
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,20 @@ rec {
|
||||||
netArgs = { mac, netdev ? "user,id=net0", extra ? "" }:
|
netArgs = { mac, netdev ? "user,id=net0", extra ? "" }:
|
||||||
"-netdev ${netdev} -device virtio-net-pci,netdev=net0,mac=${mac},bus=pcie.0,addr=${nicAddr}${extra}";
|
"-netdev ${netdev} -device virtio-net-pci,netdev=net0,mac=${mac},bus=pcie.0,addr=${nicAddr}${extra}";
|
||||||
|
|
||||||
# Devices macOS needs (no accel, disks, display adapter or display server here)
|
# Devices macOS needs (no accel, disks, display adapter or display server here).
|
||||||
deviceArgs = ''-device isa-applesmc,osk="${osk}" -smbios type=2 -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0 -device usb-tablet,bus=xhci.0 -device usb-ehci,id=ehci -device ich9-intel-hda -device hda-duplex -device ich9-ahci,id=sata -global ICH9-LPC.disable_s3=1'';
|
# No isa-applesmc: QEMU's stub only answers the OSK keys, and its presence makes
|
||||||
|
# VirtualSMC (which carries the OSK itself) step aside, leaving Apple's SMC
|
||||||
|
# driver on the stub — whose missing watchdog keys panic the restart path on
|
||||||
|
# macOS 26. VirtualSMC alone is the standard Hackintosh setup.
|
||||||
|
deviceArgsFor = { appleSmc ? false }:
|
||||||
|
''${lib.optionalString appleSmc ''-device isa-applesmc,osk="${osk}" ''}-smbios type=2 -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0 -device usb-tablet,bus=xhci.0 -device usb-ehci,id=ehci -device ich9-intel-hda -device hda-duplex -device ich9-ahci,id=sata -global ICH9-LPC.disable_s3=1'';
|
||||||
|
deviceArgs = deviceArgsFor { };
|
||||||
|
|
||||||
# macOS has no QXL/virtio-gpu driver; VMware SVGA gives a plain framebuffer
|
# macOS has no QXL/virtio-gpu driver; VMware SVGA gives a plain framebuffer
|
||||||
vgaArgs = "-vga vmware";
|
vgaArgs = "-vga vmware";
|
||||||
|
|
||||||
machineArgs = { cpu ? defaultCpu, smp ? 4, memSize ? 4096 }:
|
machineArgs = { cpu ? defaultCpu, smp ? 4, memSize ? 4096, appleSmc ? false }:
|
||||||
"-accel kvm -machine type=q35 -cpu ${cpu} -smp ${toString smp},sockets=1,cores=${toString smp},threads=1 -m ${toString memSize} ${deviceArgs} ${vgaArgs}";
|
"-accel kvm -machine type=q35 -cpu ${cpu} -smp ${toString smp},sockets=1,cores=${toString smp},threads=1 -m ${toString memSize} ${deviceArgsFor { inherit appleSmc; }} ${vgaArgs}";
|
||||||
|
|
||||||
# SATA disk on a given port. Store files are read-only: callers create qcow2 overlays.
|
# SATA disk on a given port. Store files are read-only: callers create qcow2 overlays.
|
||||||
sataDrive = { id, port, file, format ? "qcow2", extra ? "" }:
|
sataDrive = { id, port, file, format ? "qcow2", extra ? "" }:
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import shutil
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -188,17 +189,25 @@ class Serial:
|
||||||
|
|
||||||
|
|
||||||
def prepare_debug_dir(path):
|
def prepare_debug_dir(path):
|
||||||
os.makedirs(path, exist_ok=True)
|
"""Create the debug dir; builds run as different nixbld users, so the parent
|
||||||
|
is made world-writable and a temp dir is used if the path is not writable."""
|
||||||
|
parent = os.path.dirname(path)
|
||||||
try:
|
try:
|
||||||
|
if not os.path.isdir(parent):
|
||||||
|
os.makedirs(parent, exist_ok=True)
|
||||||
|
os.chmod(parent, 0o777)
|
||||||
|
os.makedirs(path, exist_ok=True)
|
||||||
os.chmod(path, 0o777)
|
os.chmod(path, 0o777)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
path = tempfile.mkdtemp(prefix=os.path.basename(path) + '-', dir='/tmp')
|
||||||
|
os.chmod(path, 0o777)
|
||||||
for f in os.listdir(path):
|
for f in os.listdir(path):
|
||||||
if f.endswith(('.png', '.ppm', '.log')) or f.startswith('.grab-') or f == 'qmp.sock':
|
if f.endswith(('.png', '.ppm', '.log')) or f.startswith('.grab-') or f == 'qmp.sock':
|
||||||
try:
|
try:
|
||||||
os.remove(os.path.join(path, f))
|
os.remove(os.path.join(path, f))
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def launch(qemu_args, qmp_sock, log):
|
def launch(qemu_args, qmp_sock, log):
|
||||||
|
|
@ -270,9 +279,9 @@ def drive(args, proc, qmp, screen, serial, log):
|
||||||
log(f'kernel panic #{panics}, giving up')
|
log(f'kernel panic #{panics}, giving up')
|
||||||
proc.kill()
|
proc.kill()
|
||||||
return 3
|
return 3
|
||||||
log(f'kernel panic #{panics}, system_reset')
|
# XNU reboots by itself after a panic; only reset if no kernel comes back
|
||||||
qmp.system_reset()
|
log(f'kernel panic #{panics}, waiting for the guest to reboot')
|
||||||
screen.stable_since = time.time()
|
serial.reboot_at = now
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# The guest asked for a reboot but no kernel came back: macOS' restart
|
# The guest asked for a reboot but no kernel came back: macOS' restart
|
||||||
|
|
@ -351,7 +360,9 @@ def drive(args, proc, qmp, screen, serial, log):
|
||||||
log('QEMU exited after powerdown')
|
log('QEMU exited after powerdown')
|
||||||
return 0
|
return 0
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
log('guest ignored powerdown, killing QEMU')
|
# macOS ignores the power button at the Setup Assistant; the
|
||||||
|
# volumes are journaled (APFS) and the PE mounts them cleanly next
|
||||||
|
log('guest ignores the ACPI power button here (Setup Assistant); stopping QEMU')
|
||||||
proc.kill()
|
proc.kill()
|
||||||
return 0
|
return 0
|
||||||
continue
|
continue
|
||||||
|
|
@ -395,7 +406,7 @@ def main():
|
||||||
p.error('QEMU command line required after --')
|
p.error('QEMU command line required after --')
|
||||||
|
|
||||||
debug_dir = args.debug_dir or f'/tmp/vmix-macos/{args.name}'
|
debug_dir = args.debug_dir or f'/tmp/vmix-macos/{args.name}'
|
||||||
prepare_debug_dir(debug_dir)
|
debug_dir = prepare_debug_dir(debug_dir)
|
||||||
log = Log(os.path.join(debug_dir, 'driver.log'))
|
log = Log(os.path.join(debug_dir, 'driver.log'))
|
||||||
log(f'mode={args.mode} debug-dir={debug_dir} serial={args.serial_log}')
|
log(f'mode={args.mode} debug-dir={debug_dir} serial={args.serial_log}')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,28 @@
|
||||||
"fetchRecoveryScript": {
|
"fetchRecoveryScript": {
|
||||||
"url": "https://raw.githubusercontent.com/kholia/OSX-KVM/4c378a4b5e0b219783683012bec680325eb40719/fetch-macOS-v2.py",
|
"url": "https://raw.githubusercontent.com/kholia/OSX-KVM/4c378a4b5e0b219783683012bec680325eb40719/fetch-macOS-v2.py",
|
||||||
"sha256": "39ac6d26bd265f5d32198062f515ad15ef93afb7a74e702be2b008090d5bd5f3"
|
"sha256": "39ac6d26bd265f5d32198062f515ad15ef93afb7a74e702be2b008090d5bd5f3"
|
||||||
|
},
|
||||||
|
"kexts": {
|
||||||
|
"Lilu": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"url": "https://github.com/acidanthera/Lilu/releases/download/1.7.2/Lilu-1.7.2-RELEASE.zip",
|
||||||
|
"hash": "sha256-U5Z9fc+qsBAjoz3y6WmolSLxPWZUpqVqxHEbYtq/Org="
|
||||||
|
},
|
||||||
|
"VirtualSMC": {
|
||||||
|
"version": "1.3.7",
|
||||||
|
"url": "https://github.com/acidanthera/VirtualSMC/releases/download/1.3.7/VirtualSMC-1.3.7-RELEASE.zip",
|
||||||
|
"hash": "sha256-EvHTeZafkmMG+pLZTdvzOzKzEXZYncQgidhkomsxtwA="
|
||||||
|
},
|
||||||
|
"WhateverGreen": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"url": "https://github.com/acidanthera/WhateverGreen/releases/download/1.7.0/WhateverGreen-1.7.0-RELEASE.zip",
|
||||||
|
"hash": "sha256-bW/+gzStYPeEpmJ5TmeyVgt511fVBoQdyMqZlKs5l5s="
|
||||||
|
},
|
||||||
|
"RestrictEvents": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"url": "https://github.com/acidanthera/RestrictEvents/releases/download/1.1.6/RestrictEvents-1.1.6-RELEASE.zip",
|
||||||
|
"hash": "sha256-mBcN+uGV3dKLXZXj8EASWhPKeDvLm9HluMWI4hexTuY="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue