Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/run-builds.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# EFI build script for OSX Hyper-V
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/oce-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,19 @@ jobs:
name: Validate OCE-Build output
shell: pwsh
run: |
$OCVALIDATE = 'dist\Utilities\ocvalidate\ocvalidate.exe';
$PLIST_PATH = 'dist\EFI\OC\config.plist';
Start-Process -Wait $OCVALIDATE -NoNewWindow -ArgumentList $PLIST_PATH;
& 'dist\Utilities\ocvalidate\ocvalidate.exe' 'dist\EFI\OC\config.plist' |
Tee-Object -FilePath ocvalidate.log
if (Select-String -Path ocvalidate.log -Pattern 'Found \d+ issues') {
Write-Error "Validation failed, please check output for details."
exit 1
}
# Handles compression and lock-hash generation for upload task.
#
# This stores a hash of the output build's lockfile to associate with the
# output EFI directory. This is useful when running concurrent builds with
# this workflow in a matrix for testing prior or future OpenCore versions.
- id: prepare-efi
if: always()
name: Prepares EFI directory for upload
shell: sh
run: |
Expand All @@ -89,7 +93,9 @@ jobs:
# Uploads EFI with a short-sha slug. The uploaded EFI will be available
# for download after the current job run as finished.
- name: Upload built EFI
if: always()
uses: actions/upload-artifact@v4
with:
name: EFI-${{ steps.prepare-efi.outputs.LOCKFILE_HASH }}
path: EFI.zip
path: EFI.zip
retention-days: 7
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
BSD 3-Clause License

Copyright (c) 2021, Goldfish64
Copyright (c) 2021-2025, Goldfish64

Copyright (c) 2023, Cory Bennett
Copyright (c) 2023-2025, Cory Bennett
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
22 changes: 22 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

The latest progress can be viewed on this repository's [project board](#).

## [0.3.0] - Unreleased

A major update introducing significant improvements, new features, and internal refactoring for enhanced compatibility and user experience.

This release modernizes the Hyper-V integration stack with updated kexts, automation scripts, and configuration changes, streamlining macOS installation and post-installation on Hyper-V VMs.

## Changed
- Update License to match upstream ([`3498a02`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/3498a023644184ec8086442365b64cf12998212e))
- Update ACPI patches; remove WS2022 SSDT ([`1d3e69b`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/1d3e69bf29af5e50e7350259bacfd2908c815d06))
- Update OpenCore and MacHyperVSupport versions ([`ac04dd0`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/ac04dd034665250b9c3320b3b12aa2988b370a77))
- Fix IOGraphicsFamily paths and remove MaxKernel version ([`feed097`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/feed09783784373528a4ba9e934339eda1c0fe1e))
- Remove ACPI0007 objects from SSDT-HV-DEV [`238b571`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/238b571e16ef857ffa5eaf7a390f16162774f7fa)
- Remove VMHide kext, replacing with direct `hv_vmm_present` kernel patch ([`a377f97`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/a377f977d1c4b48d4630c5c48fa4006474b9196f); see [#46](https://github.com/Qonfused/OSX-Hyper-V/issues/46#issuecomment-2813907377))
- Disable MacHyperVFramebuffer injection (kept for post-install use) ([`a19f660`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/a19f660b95e1e4f397c9b0ccb581496e3cf0b725))

## Added
- Add MacHyperVFramebuffer kext and update configuration ([`f2eb5a1`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/f2eb5a1b88d3fe802df57e40135049dab2d98351))
- Add post-install script to automate installation of Hyper-V daemons and MacHyperVFramebuffer ([`d888782`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/d888782fbb726e762a80d35609d03ed497bc93b3))

## Fixed
- Update README and post-install script instructions ([`aabc21a`](https://github.com/Qonfused/OSX-Hyper-V/pull/40/commits/aabc21a61cc1d098eea4b5becf277f6f35ed06f4))

## [0.2.4] - 2025-01-22

## Changed
Expand Down
60 changes: 57 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<a href="/LICENSE">![License](https://img.shields.io/badge/⚖_License-BSD_3_Clause-lightblue?labelColor=3f4551)</a>
<a href="/docs/CHANGELOG.md">![SemVer](https://img.shields.io/github/v/release/Qonfused/OSX-Hyper-V?label=SemVer&logo=SemVer&labelColor=3f4551)</a>
<a href="">![macOS Versions](https://img.shields.io/badge/macOS%20Versions-10.4%20to%2015-important?labelColor=3f4551)</a>
<a href="https://github.com/acidanthera/OpenCorePkg/releases">![OpenCore](https://img.shields.io/badge/OpenCore-1.0.3-0c7dbe?logo=Osano&logoColor=0298e1&labelColor=3f4451)</a>
<a href="https://github.com/acidanthera/OpenCorePkg/releases">![OpenCore](https://img.shields.io/badge/OpenCore-1.0.4-0c7dbe?logo=Osano&logoColor=0298e1&labelColor=3f4451)</a>
<a href="https://github.com/Qonfused/OSX-Hyper-V/actions/workflows/oce-build.yml">![OCE Build](https://github.com/Qonfused/OSX-Hyper-V/actions/workflows/oce-build.yml/badge.svg?branch=main)</a>

</div>
Expand Down Expand Up @@ -614,6 +614,9 @@ First check that you've [enabled Hyper-V](https://learn.microsoft.com/en-us/virt
> .\Scripts\create-virtual-machine.ps1 -name "Catalina" -version 10.15 -cpu 4 -ram 16 -size 128
> ```

> [!IMPORTANT]
> Newer macOS versions (Big Sur and newer) require 6-8 GB of RAM to boot the installer. If you are using an older version of macOS, you can use less RAM (4 GB is the minimum).

Below outline the steps to manually create a new virtual machine for macOS:

---
Expand Down Expand Up @@ -698,16 +701,67 @@ Then configure the below options under the Hardware section:

Refer to the [Installation Process][Dortania-Guide/Installation-Process] section of the Dortania Guide. Some additional post-install sections are provided to facilitate with Hyper-V (or project) specifics.

<!--
Another user's suggestion for installation steps (for reference):
1. Run PS script to create VM
2. Start VM, open Console
3. boot to EFI (dmg) to launch recovery menu
4. Enter Disk Utility
5. Choose "Msft Virtual Disk Media", Select "Erase"
6. Name new drive "MyInteralDrive", choose AFPS for filesystem format
7. Execute Erase
8. Quit Disk Utility
9. Back at main menu for the Recovery program, choose "Reinstall macOS "
10. Select your newly minted AFPS-formatted disk
11. Let macOS do it's thing for approx 2 hours.
-->

A basic summary of the installation process is as follows:

1. Start the virtual machine and select the `EFI (dmg)` from the OpenCore boot menu.
- If you created a separate macOS installer VHDX, this may also show up as `macOS Base System (External)` or `Install macOS Big Sur (External)` depending on the version of macOS you are installing.
2. Once the installer loads, open Disk Utility from the Utilities menu.
- Select the `Msft Virtual Disk Media` (your main virtual hard disk) from the list of disks.
- Click `Erase` to format the disk.
- Name the disk as desired (e.g., `macOS` or `Macintosh HD`, etc.).
- For macOS 10.13 and newer, use the `APFS` format. For older versions, use `Mac OS Extended (Journaled)`.
4. Quit Disk Utility and return to the main installer menu.
5. Select `Reinstall macOS` to start the main installer.
- Follow the prompts to install macOS on your newly formatted disk.
- Make sure to target the disk you just formatted (e.g., `macOS` or whatever you named it), not the EFI disk.
- Note that this process may take a while (upwards of 30 minutes to 2 hours).
6. Once the installation is complete, the virtual machine will reboot and you should see the OpenCore boot menu again.
- This may require multiple reboots to install additional components and finalize the installation.
7. Select the newly installed macOS disk (or whatever you named it) from the OpenCore boot menu to boot into macOS.
- If you are still unable to boot into your macOS installation, you may need to select the installer disk again.
- You can set this as the default boot entry by holding the `Ctrl` key while selecting the disk.

The EFI virtual disk created by this project bundles a post-installation script responsible for installing the **MacHyperVFramebuffer** driver and configuring daemons for additional Hyper-V service support. This is required to support resolution changes and the hardware cursor in macOS.

To run this script, execute the `post-install.sh` script from the EFI disk located in the `Scripts/` directory. For example, you can run the following command in Terminal after booting into the macOS installer:

```bash
cd /Volumes/EFI # Change to the EFI disk
bash ./Scripts/post-install.sh
```

You can also optionally run the `optimize-vm.sh` script to disable Spotlight indexing, reduce disk I/O, and turn off system animations. This is recommended for virtual machines with CPU-rendered graphics and limited disk performance.

```bash
cd /Volumes/EFI # Change to the EFI disk
bash ./Scripts/optimize-vm.sh
```

[Dortania-Guide/Installation-Process]: https://dortania.github.io/OpenCore-Install-Guide/installation/installation-process.html

#### Limitations

There are some known limitations with the base configuration for Hyper-V:

- Display Resolution
- The default virtual display resolution is set to a 1024x768 resolution and is not resizable.
- The default virtual display resolution is set to a 1024x768 resolution, but can be reconfigured by modifying the `SupportedResolutions` entry in MacHyperVFramebuffer's Info.plist file. See issue #6 for more details.
- Graphics Acceleration
- By default, macOS will run without graphics acceleration using VESA graphics drivers (CPU). Additionally, display graphics is limited to 3 MB of video memory.
- By default, macOS will run using the MacHyperVFramebuffer synthetic graphics driver, which provides basic graphics support (with 8 MB of video memory). This driver is sufficient for basic tasks, but does not provide hardware acceleration or advanced graphics features.
- GPU acceleration is possible through [Discrete Device Assignment (DDA)][aka.ms/dda] using a supported GPU, however there exist a couple major caveats:
- AMD GPUs (particularly Navi and older GPUs) generally have poor compatibility with macOS through DDA. Natively supported NVIDIA GPUs (using driver v465 or later on Windows) tend to have the best results.
- GPU patching with Lilu and WhateverGreen is currently not supported (refer to [#2299](https://github.com/acidanthera/bugtracker/issues/2299) for tracking). This also applies to other kexts like NootedRed/NootedRX that use Lilu.
Expand Down
3 changes: 2 additions & 1 deletion scripts/build.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# EFI build script for OSX Hyper-V
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand All @@ -27,6 +27,7 @@ function HasFlag {
}

# Switches for additional '--legacy' and '--32-bit' patches
# TODO: Add switch for legacy iASL for macOS 10.6 and older
$patches = @('-p config.yml')
if (HasFlag '--legacy') { $patches += @('-p patch.legacy.yml') }
if (HasFlag '--32-bit') {
Expand Down
27 changes: 26 additions & 1 deletion scripts/lib/convert-efi-disk.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# EFI VHDX conversion script for Hyper-V
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down Expand Up @@ -29,6 +29,31 @@ $efiDisk = New-VHD -Path "$dest" -Dynamic -SizeBytes 5GB |
# Copy EFI folder to VHDX disk
Copy-Item -Path "$path" -Recurse -Destination "$($efiDisk.DriveLetter):\EFI"

# Copy the Scripts directory (for post-install scripts)
$scriptsDir = "$pwd\dist\Scripts"
if (Test-Path -Path $scriptsDir) {
# Only copy shell scripts (.sh) intended for post-install
$postInstallScripts = Get-ChildItem -Path $scriptsDir -Filter "*.sh" -Recurse
if ($postInstallScripts) {
foreach ($script in $postInstallScripts) {
$destinationPath = "$($efiDisk.DriveLetter):\Scripts\$($script.Name)"
Copy-Item -Path $script.FullName -Destination $destinationPath -Force
Write-Host "Copied script: $($script.Name) to $destinationPath"
}
}
} else {
Write-Host "Scripts directory not found at $scriptsDir. Skipping copy."
}

# Copy the Tools directory (for post-install daemons)
$toolsDir = "$pwd\dist\Tools"
if (Test-Path -Path $toolsDir) {
Copy-Item -Path $toolsDir -Recurse -Destination "$($efiDisk.DriveLetter):\Tools"
Write-Host "Copied Tools directory to $($efiDisk.DriveLetter):\Tools"
} else {
Write-Host "Tools directory not found at $toolsDir. Skipping copy."
}

# Copy macOS recovery image if present
$recoveryImage = "com.apple.recovery.boot"
if (Test-Path -Path "$($pwd)\$recoveryImage") {
Expand Down
2 changes: 1 addition & 1 deletion scripts/lib/create-macos-recovery.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# macrecovery.py wrapper script
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down
2 changes: 1 addition & 1 deletion scripts/lib/create-virtual-machine.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# Hyper-V virtual machine creation script
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down
2 changes: 1 addition & 1 deletion scripts/lib/optimize-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## @file
# Post-Install script - Optimizes macOS virtual machines for Hyper-V
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down
105 changes: 105 additions & 0 deletions scripts/lib/post-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091,SC2164

## @file
# MacHyperVSupport post-install script
#
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

# Change CWD for imports
__PWD__=$(pwd); cd "$(realpath "$(dirname "${BASH_SOURCE[0]}")"/../)"

# Check if the Tools/ directory exists
if [[ ! -d "Tools" ]]; then
echo "Tools directory not found. This script must be ran from the Scripts directory inside the EFI volume."
exit 1
fi

if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root (use sudo or run as root user)."
exit 1
fi


PKG_BUILD_DIR="/tmp/pkg-build"
APP_SUPPORT_DIR="/Library/Application Support/MacHyperVSupport"
LAUNCH_DAEMON_DIR="/Library/LaunchDaemons"

sudo mkdir -p "${APP_SUPPORT_DIR}"
sudo mkdir -p "${LAUNCH_DAEMON_DIR}"


copy_daemon() {
local daemon_path="$1"
local plist_path="$2"

local daemon_name="${daemon_path##*/}"
local plist_name="${plist_path##*/}"

if [[ -f "${daemon_path}" && -f "${plist_path}" ]]; then
# Unload the daemon if it's already loaded
if sudo launchctl list | grep -q "${daemon_name}"; then
echo "Unloading existing daemon: ${daemon_name}"
sudo launchctl unload "${LAUNCH_DAEMON_DIR}/${plist_name}"
fi

# Copy the daemon and plist to the appropriate directories
sudo cp "${daemon_path}" "${APP_SUPPORT_DIR}/"
sudo cp "${plist_path}" "${LAUNCH_DAEMON_DIR}/"

# Set ownership and permissions
sudo chown root:wheel "${APP_SUPPORT_DIR}/${daemon_name}"
sudo chmod 755 "${APP_SUPPORT_DIR}/${daemon_name}"
sudo chown root:wheel "${LAUNCH_DAEMON_DIR}/${plist_name}"
sudo chmod 644 "${LAUNCH_DAEMON_DIR}/${plist_name}"

# Load the daemon
sudo launchctl load "${LAUNCH_DAEMON_DIR}/${plist_name}"
else
echo "Daemon or plist file for ${daemon_name} not found."
fi
}


# Install each Hyper-V daemon to launchd
(
cd "Tools" || { echo "Failed to change directory to Tools."; exit 1; }

for plist in fish.goldfish64.*; do
[ -e "${plist}" ] || continue
# Extract the daemon name from the plist
daemon="${plist%.plist}"
daemon="${daemon#fish.goldfish64.}"
if [[ -f "${daemon}" ]]; then
echo "Installing daemon: ${daemon}"
copy_daemon "${daemon}" "${plist}"
fi
done
)


FRAMEBUFFER_KEXT="EFI/OC/Kexts/MacHyperVFramebuffer.kext"
if [[ -d "${FRAMEBUFFER_KEXT}" ]]; then
# Unload the kext if it's already loaded
if kextstat | grep -q "com.apple.driver.MacHyperVFramebuffer"; then
echo "Unloading existing MacHyperVFramebuffer kext..."
sudo kextunload /Library/Extensions/MacHyperVFramebuffer.kext
fi

echo "Installing MacHyperVFramebuffer kext...\n"
echo "This will prompt you to approve the developer in System Settings > Privacy & Security required to load the kext."
echo "You will need to reboot your virtual machine after this step to complete the installation."
sudo cp -R "${FRAMEBUFFER_KEXT}" "/Library/Extensions/"
sudo chown -R root:wheel "/Library/Extensions/MacHyperVFramebuffer.kext"
sudo chmod -R 755 "/Library/Extensions/MacHyperVFramebuffer.kext"

echo "Loading MacHyperVFramebuffer kext..."
sudo kextload "/Library/Extensions/MacHyperVFramebuffer.kext"

echo "Rebuilding kext cache..."
sudo kextcache -i /
else
echo "MacHyperVFramebuffer kext could not be found. Please ensure it exists in the EFI/OC/Kexts directory."
fi
2 changes: 1 addition & 1 deletion scripts/post-build.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## @file
# EFI build script for OSX Hyper-V
#
# Copyright (c) 2023, Cory Bennett. All rights reserved.
# Copyright (c) 2023-2025, Cory Bennett. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
##

Expand Down
Loading