diff --git a/CHANGELOG.md b/CHANGELOG.md
index be4b5c8caa..c0402df8c0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,14 @@
- Increment Binaries:
- OpenCorePkg 1.0.5 - rolling (f03819e)
+## 2.5.0
+- Disable repatching a dirty root volume
+ - Prevents issues if existing patches are partially overwritten
+ - Thanks @crystall1nedev!
+- Add slimmed down patchset for Modern Wireless for macOS Sequoia
+- Increment binaries:
+ - PatcherSupportPkg 1.9.6 - release
+
## 2.4.1
- Switch installer source to AppleDB
- Resolves missing or incorrect installers showing up when downloading an installer
diff --git a/docs/ACCEL.md b/docs/ACCEL.md
new file mode 100644
index 0000000000..82f0274180
--- /dev/null
+++ b/docs/ACCEL.md
@@ -0,0 +1,10 @@
+This page has moved.
+
+
+
+* [Application troubleshooting](./TROUBLESHOOT-APP.md)
+* [Booting, installer and other troubleshooting](./TROUBLESHOOT-MISC.md)
+* [Non-Metal troubleshooting](./TROUBLESHOOT-NONMETAL.md)
+* [Hardware troubleshooting](./TROUBLESHOOT-HARDWARE.md)
+
+
diff --git a/docs/BOOT.md b/docs/BOOT.md
index 93f1b4f140..4f866b5bce 100644
--- a/docs/BOOT.md
+++ b/docs/BOOT.md
@@ -93,7 +93,7 @@ When installing macOS Sonoma or newer on a T1 system (2016-2017), full disk wipe
-[More info here](https://dortania.github.io/OpenCore-Legacy-Patcher/TROUBLESHOOTING.html#no-t1-functionality-after-installing-sonoma-or-newer)
+[More info here](https://dortania.github.io/OpenCore-Legacy-Patcher/TROUBLESHOOT-HARDWARE.html#no-t1-functionality-after-installing-sonoma-or-newer)
:::
diff --git a/docs/TROUBLESHOOT-NONMETAL.md b/docs/TROUBLESHOOT-NONMETAL.md
index 8fbf5fcbb1..5308a622f0 100644
--- a/docs/TROUBLESHOOT-NONMETAL.md
+++ b/docs/TROUBLESHOOT-NONMETAL.md
@@ -14,7 +14,7 @@ The below page is for users experiencing issues with their overall usage of macO
## Broken Firefox and Thunderbird (HD 3000)
-[Due to removal of HD 3000 support workarounds](https://hg-edge.mozilla.org/releases/mozilla-release/rev/32d4368e5a2a869bdc1f4556f020c1a6bea2a9c0) in Firefox/Thunderbird v145, Firefox and Thunderbird on HD 3000 are now broken. This may lead to system freezes and other erratic behavior on systems with this GPU, which is found in Mac models from 2011. As a workaround, hardware acceleration has to be disabled. If your system is locking up in normal mode, boot into Safe Mode by holding `Shift` on boot and disable hardware acceleration for Firefox and Thunderbird wherever applicable.
+Firefox and Thunderbird are now broken on HD 3000 [due to removal of HD 3000 support by Mozilla in v145.](https://hg-edge.mozilla.org/releases/mozilla-release/rev/32d4368e5a2a869bdc1f4556f020c1a6bea2a9c0) This may lead to system freezes and other erratic behavior on systems with this GPU, which is found in Mac models from 2011. As a workaround, hardware acceleration has to be disabled. If your system is locking up in normal mode, boot into Safe Mode by holding `Shift` on boot and disable hardware acceleration for Firefox and Thunderbird wherever applicable.
::: details Affected Mac models (click to expand)
diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md
new file mode 100644
index 0000000000..1e9dd6ce1d
--- /dev/null
+++ b/docs/TROUBLESHOOTING.md
@@ -0,0 +1,6 @@
+This page has moved.
+
+- [Application troubleshooting](./TROUBLESHOOT-APP.md)
+- [Booting, installer and other troubleshooting](./TROUBLESHOOT-MISC.md)
+- [Non-Metal troubleshooting](./TROUBLESHOOT-NONMETAL.md)
+- [Hardware troubleshooting](./TROUBLESHOOT-HARDWARE.md)
diff --git a/docs/UNINSTALL.md b/docs/UNINSTALL.md
index 28fc6a5a97..a26f5a3d6b 100644
--- a/docs/UNINSTALL.md
+++ b/docs/UNINSTALL.md
@@ -4,12 +4,16 @@ This guide tells you different ways to uninstall OCLP and/or patches.
## Delete everything and revert back to native macOS
-1. Create a USB drive with the latest officially supported macOS installer.
-2. Restart the computer and [Reset NVRAM.](https://support.apple.com/HT204063)
-3. Boot the computer using the installer USB drive.
+1. Create a USB drive with the latest officially supported macOS installer or alternatively [on most Macs](https://apple.stackexchange.com/questions/383985/which-macs-support-macos-internet-recovery) use Internet Recovery.
+ * Hold `cmd` + `Option (Alt)` + `R` for Internet Recovery.
+ * If doing Internet Recovery, skip step 2.
+ * Caution: Internet Recovery may not always install the latest officially supported OS version.
+3. Restart and boot the computer using the installer USB drive by holding `Option (Alt)`.
4. Go to Disk Utility and choose View -> Show All Devices.
5. Wipe the full disk by choosing the top disk option on the left sidebar and selecting "Erase".
6. Start macOS installation.
+7. Once finished, restart once more and [Reset NVRAM](https://support.apple.com/HT204063) to ensure a fully clean and stock system.
+
## Manual methods
diff --git a/opencore_legacy_patcher/constants.py b/opencore_legacy_patcher/constants.py
index 1351bbdf9d..93789c86a9 100644
--- a/opencore_legacy_patcher/constants.py
+++ b/opencore_legacy_patcher/constants.py
@@ -14,7 +14,7 @@ class Constants:
def __init__(self) -> None:
# Patcher Versioning
self.patcher_version: str = "3.0.0" # OpenCore-Legacy-Patcher
- self.patcher_support_pkg_version: str = "1.9.5" # PatcherSupportPkg
+ self.patcher_support_pkg_version: str = "1.9.6" # PatcherSupportPkg
self.copyright_date: str = "Copyright © 2020-2025 Dortania"
self.patcher_name: str = "OpenCore Legacy Patcher"
@@ -880,4 +880,4 @@ def icons_path(self):
"Mac-942B59F58194171B", # iMac12,2
"Mac-94245AF5819B141B", # AppleInternal MacBookPro8,3
"Mac-942B5B3A40C91381", # AppleInternal iMac12,2
- ]
\ No newline at end of file
+ ]
diff --git a/opencore_legacy_patcher/efi_builder/firmware.py b/opencore_legacy_patcher/efi_builder/firmware.py
index c247a6cd50..989a38bdf7 100644
--- a/opencore_legacy_patcher/efi_builder/firmware.py
+++ b/opencore_legacy_patcher/efi_builder/firmware.py
@@ -197,7 +197,7 @@ def _cpu_compatibility_handling(self) -> None:
# HID patches
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.CPUGen.penryn.value:
logging.info("- Adding IOHIDFamily patch")
- support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.iokit.IOHIDFamily")["Enabled"] = True
+ support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Patch IOHIDFamily")["Enabled"] = True
# MacPro3,1/Xserve2,1 cannot boot with more than 4 threads in Sequoia
# Note cpus=4 only overrides if more than 4 threads are present. So same on dual-core units
diff --git a/opencore_legacy_patcher/efi_builder/misc.py b/opencore_legacy_patcher/efi_builder/misc.py
index 5916d2c96e..ba313bd1da 100644
--- a/opencore_legacy_patcher/efi_builder/misc.py
+++ b/opencore_legacy_patcher/efi_builder/misc.py
@@ -221,6 +221,7 @@ def _topcase_handling(self) -> None:
support.BuildSupport(self.model, self.constants, self.config).enable_kext("LegacyKeyboardInjector.kext", self.constants.legacy_keyboard, self.constants.legacy_keyboard_path)
if self.computer.trackpad_type == "Legacy":
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleUSBTrackpad.kext", self.constants.apple_trackpad, self.constants.apple_trackpad_path)
+ support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Fix IOHIDFamily USB topcase panic")["Enabled"] = True
elif self.computer.trackpad_type == "Modern":
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleUSBMultitouch.kext", self.constants.multitouch_version, self.constants.multitouch_path)
@@ -236,6 +237,7 @@ def _topcase_handling(self) -> None:
support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyboard.kext")["Enabled"] = True
support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyEventDriver.kext")["Enabled"] = True
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleUSBMultitouch.kext", self.constants.multitouch_version, self.constants.multitouch_path)
+ support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Fix IOHIDFamily USB topcase panic")["Enabled"] = True
# Two-finger Top Case support for macOS High Sierra+
if self.model == "MacBook5,2":
diff --git a/opencore_legacy_patcher/sys_patch/patchsets/detect.py b/opencore_legacy_patcher/sys_patch/patchsets/detect.py
index 8f04b23fcb..7bfa660d5b 100644
--- a/opencore_legacy_patcher/sys_patch/patchsets/detect.py
+++ b/opencore_legacy_patcher/sys_patch/patchsets/detect.py
@@ -90,6 +90,7 @@ class HardwarePatchsetValidation(StrEnum):
NVDA_DRV_MISSING = "Validation: nvda_drv(_vrl) variable missing"
PATCHING_NOT_POSSIBLE = "Validation: Patching not possible"
UNPATCHING_NOT_POSSIBLE = "Validation: Unpatching not possible"
+ REPATCHING_NOT_SUPPORTED = "Validation: Root volume dirty, unpatch to continue"
class HardwarePatchsetDetection:
@@ -187,6 +188,42 @@ def _validation_check_filevault_is_enabled(self) -> bool:
return "FileVault is Off" not in subprocess.run(["/usr/bin/fdesetup", "status"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
+
+ def _validation_check_repatching_is_possible(self) -> bool:
+ """
+ Determine if repatching is not allowed
+ """
+ oclp_patch_path = "/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist"
+ if not Path(oclp_patch_path).exists():
+ return self._is_root_volume_dirty()
+
+ oclp_plist = plistlib.load(open(oclp_patch_path, "rb"))
+
+ if self._constants.computer.oclp_sys_url != self._constants.commit_info[2]:
+ logging.error("Installed patches are from different commit, unpatching is required")
+ return True
+
+ wireless_keys = {"Legacy Wireless", "Modern Wireless Common"}
+
+ # Keep in sync with generate_patchset_plist
+ metadata_keys = {
+ "OpenCore Legacy Patcher",
+ "PatcherSupportPkg",
+ "Time Patched",
+ "Commit URL",
+ "Kernel Debug Kit Used",
+ "Metal Library Used",
+ "OS Version",
+ "Custom Signature",
+ }
+
+ existing_patches = set(oclp_plist) - wireless_keys - metadata_keys
+ if existing_patches:
+ logging.error(f"Patch(es) already installed: {', '.join(existing_patches)}, unpatching is required")
+ return True
+
+ return False
+
def _validation_check_system_integrity_protection_enabled(self, configs: list[str]) -> bool:
"""
@@ -310,6 +347,28 @@ def _is_cached_metallib_support_pkg_present(self) -> bool:
"""
return metallib_handler.MetalLibraryObject(self._constants, self._os_build, self._os_version).metallib_already_installed
+
+ def _is_root_volume_dirty(self) -> bool:
+ """
+ Determine if system volume is not sealed
+ """
+ # macOS 11.0 introduced sealed system volumes
+ if self._xnu_major < os_data.big_sur.value:
+ return False
+
+ try:
+ content = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", "/"], capture_output=True).stdout)
+ except plistlib.InvalidFileException:
+ raise RuntimeError("Failed to parse diskutil output.")
+
+ seal = content["Sealed"]
+
+ if "Broken" in seal:
+ logging.error(f"System volume is tainted, unpatching is required")
+ return True
+
+ return False
+
def _can_patch(self, requirements: dict, ignore_keys: list[str] = []) -> bool:
"""
@@ -503,6 +562,7 @@ def _detect(self) -> None:
HardwarePatchsetValidation.SIP_ENABLED: self._validation_check_system_integrity_protection_enabled(required_sip_configs),
HardwarePatchsetValidation.SECURE_BOOT_MODEL_ENABLED: self._validation_check_secure_boot_model_enabled(),
HardwarePatchsetValidation.AMFI_ENABLED: self._validation_check_amfi_enabled(highest_amfi_level),
+ HardwarePatchsetValidation.REPATCHING_NOT_SUPPORTED: self._validation_check_repatching_is_possible(),
HardwarePatchsetValidation.WHATEVERGREEN_MISSING: self._validation_check_whatevergreen_missing() if has_nvidia_web_drivers is True else False,
HardwarePatchsetValidation.FORCE_OPENGL_MISSING: self._validation_check_force_opengl_missing() if has_nvidia_web_drivers is True else False,
HardwarePatchsetValidation.FORCE_COMPAT_MISSING: self._validation_check_force_compat_missing() if has_nvidia_web_drivers is True else False,
diff --git a/opencore_legacy_patcher/sys_patch/patchsets/hardware/misc/modern_audio.py b/opencore_legacy_patcher/sys_patch/patchsets/hardware/misc/modern_audio.py
index 2abf12aab0..b84e5e9359 100644
--- a/opencore_legacy_patcher/sys_patch/patchsets/hardware/misc/modern_audio.py
+++ b/opencore_legacy_patcher/sys_patch/patchsets/hardware/misc/modern_audio.py
@@ -44,6 +44,12 @@ def native_os(self) -> bool:
return False
+ def requires_kernel_debug_kit(self) -> bool:
+ """
+ Apple no longer provides standalone kexts in the base OS
+ """
+ return True
+
def hardware_variant(self) -> HardwareVariant:
"""
diff --git a/opencore_legacy_patcher/sys_patch/patchsets/hardware/networking/modern_wireless.py b/opencore_legacy_patcher/sys_patch/patchsets/hardware/networking/modern_wireless.py
index b8e421cffc..cfe1065ad0 100644
--- a/opencore_legacy_patcher/sys_patch/patchsets/hardware/networking/modern_wireless.py
+++ b/opencore_legacy_patcher/sys_patch/patchsets/hardware/networking/modern_wireless.py
@@ -52,23 +52,18 @@ def hardware_variant(self) -> HardwareVariant:
"""
return HardwareVariant.NETWORKING
-
- def patches(self) -> dict:
+ def _patches_modern_wireless_common_extended(self) -> dict:
"""
- Patches for Modern Wireless
+ Extended modern wireless patches
"""
- if self.native_os() is True:
+ if self._xnu_major > os_data.sonoma:
return {}
return {
- "Modern Wireless": {
+ "Modern Wireless Extended": {
PatchType.OVERWRITE_SYSTEM_VOLUME: {
"/usr/libexec": {
"airportd": f"13.7.2-{self._xnu_major}",
- "wifip2pd": f"13.7.2-{self._xnu_major}",
- },
- "/System/Library/CoreServices": {
- **({ "WiFiAgent.app": "14.7.2" } if self._xnu_major >= os_data.sequoia else {}),
},
},
PatchType.MERGE_SYSTEM_VOLUME: {
@@ -76,10 +71,43 @@ def patches(self) -> dict:
"CoreWLAN.framework": f"13.7.2-{self._xnu_major}",
},
"/System/Library/PrivateFrameworks": {
- "CoreWiFi.framework": f"13.7.2-{self._xnu_major}",
+ "CoreWiFi.framework": f"13.7.2-{self._xnu_major}",
+ },
+ },
+ },
+ }
+
+
+ def _patches_modern_wireless_common(self) -> dict:
+ """
+ Common modern wireless patches
+ """
+ return {
+ "Modern Wireless Common": {
+ PatchType.OVERWRITE_SYSTEM_VOLUME: {
+ "/usr/libexec": {
+ "wifip2pd": f"13.7.2-{self._xnu_major}",
+ },
+ },
+ PatchType.MERGE_SYSTEM_VOLUME: {
+ "/System/Library/PrivateFrameworks": {
"IO80211.framework": f"13.7.2-{self._xnu_major}",
"WiFiPeerToPeer.framework": f"13.7.2-{self._xnu_major}",
},
- }
+ },
},
- }
\ No newline at end of file
+ }
+
+ def patches(self) -> dict:
+ """
+ Dictionary of patches
+ """
+ if self.native_os() is True:
+ return {}
+
+ return {
+ **self._patches_modern_wireless_common(),
+ **self._patches_modern_wireless_common_extended(),
+ }
+
+ return _base
\ No newline at end of file
diff --git a/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py b/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py
index 082f21ec86..9e463b6c87 100644
--- a/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py
+++ b/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py
@@ -229,7 +229,7 @@ def _fetch_patches(self) -> None:
start_button.Disable()
else:
self.available_patches = True
- if patches[HardwarePatchsetValidation.PATCHING_NOT_POSSIBLE] is True:
+ if patches[HardwarePatchsetValidation.PATCHING_NOT_POSSIBLE] is True or no_new_patches is True:
start_button.Disable()
elif no_new_patches is False:
start_button.SetDefault()
diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist
index 868db6ee3b..c32128080b 100644
--- a/payloads/Config/config.plist
+++ b/payloads/Config/config.plist
@@ -2030,6 +2030,36 @@
Skip
0
+
+ Arch
+ x86_64
+ Base
+ __ZN11IOHIDDevice12didTerminateEP9IOServicejPb
+ Comment
+ Fix IOHIDFamily USB topcase panic
+ Count
+ 0
+ Enabled
+
+ Find
+
+ Identifier
+ com.apple.iokit.IOHIDFamily
+ Limit
+ 0
+ Mask
+
+ MaxKernel
+
+ MinKernel
+ 25.0.0
+ Replace
+ uAEAAADD
+ ReplaceMask
+
+ Skip
+ 0
+
Arch
x86_64