diff --git a/CHANGELOG.md b/CHANGELOG.md index d898a99e4..f9b0e5c23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # OpenCore Legacy Patcher changelog ## 0.4.11 +- Enable AppleMCEReporterDisabler whenever spoofing affected SMBIOS + - ie. iMacPro1,1, MacPro6,1 and MacPro7,1 +- Verify host's disk space before downloading macOS Installers +- Remove duplicate OS builds in macOS downloader + - Avoids Apple's odd bug of publishing 2 different 12.5.1 products - Ventura Specific Updates: diff --git a/docs/ACCEL.md b/docs/ACCEL.md index 730f852c3..935b0eb9a 100644 --- a/docs/ACCEL.md +++ b/docs/ACCEL.md @@ -163,8 +163,7 @@ However if your machine does not have the dGPU disabled via NVRAM, you'll experi 2. When command line prompt appears, enter the dGPU disabler argument (at the bottom) 3. Reboot and patched macOS should work normally 4. If you still want to use the dGPU, run OpenCore Legacy Patcher and enable TS2 Acceleration from settings. Then root patch your Mac again - * TUI: `Patcher Settings -> Misc Settings -> TeraScale 2 Accel` - * GUI: `Patcher Settings -> Developer Settings -> Set TeraScale 2 Accel` + `Patcher Settings -> Developer Settings -> Set TeraScale 2 Accel` 5. Either Reset NVRAM or set `gpu-power-prefs` to zeros to re-enable the dGPU ```sh @@ -184,4 +183,4 @@ A somewhat strange issue on Intel HD3000-based Macs, on 3rd party displays somet | Default Color Profile | Display/Display P3 Profile | | :--- | :--- | -| ![](../images/HD3000-Default-Colors.png) | ![](../images/HD3000-Display-Colors.png) | \ No newline at end of file +| ![](../images/HD3000-Default-Colors.png) | ![](../images/HD3000-Display-Colors.png) | diff --git a/gui/gui_main.py b/gui/gui_main.py index b71b69758..0e6e9bb58 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -881,7 +881,11 @@ class wx_python_gui: self.frame_modal.SetSize(-1, self.return_to_main_menu.GetPosition().y + self.return_to_main_menu.GetSize().height + 20) if result is True: - self.reboot_system(message="OpenCore has finished installing to disk.\n\nYou will need to reboot and hold the Option key and select OpenCore/Boot EFI's option.\n\nWould you like to reboot?") + if not self.constants.custom_model: + self.reboot_system(message="OpenCore has finished installing to disk.\n\nYou will need to reboot and hold the Option key and select OpenCore/Boot EFI's option.\n\nWould you like to reboot?") + else: + popup_message = wx.MessageDialog(self.frame,f"OpenCore has finished installing to disk.\n\nYou can eject the drive, insert it into the {self.constants.custom_model}, reboot, hold the Option key and select OpenCore/Boot EFI's option.", "Success", wx.OK) + popup_message.ShowModal() def root_patch_menu(self, event=None): # Define Menu @@ -1507,6 +1511,14 @@ class wx_python_gui: except ValueError: pass + # Ensure we have space to both download and extract the installer + host_space = utilities.get_free_space() + needed_space = app_dict['Size'] * 2 + if host_space < needed_space: + dlg = wx.MessageDialog(self.frame_modal, f"You do not have enough free space to download and extract this installer. Please free up some space and try again\n\n{utilities.human_fmt(host_space)} available vs {utilities.human_fmt(needed_space)} required", "Insufficient Space", wx.OK | wx.ICON_WARNING) + dlg.ShowModal() + return + self.frame.DestroyChildren() installer_name = f"macOS {app_dict['Version']} ({app_dict['Build']})" diff --git a/resources/build.py b/resources/build.py index 13bfbd3b8..414b5d715 100644 --- a/resources/build.py +++ b/resources/build.py @@ -112,7 +112,6 @@ class BuildOpenCore: ("RestrictEvents.kext", self.constants.restrictevents_version, self.constants.restrictevents_path, lambda: self.model in model_array.MacPro), ("SMC-Spoof.kext", self.constants.smcspoof_version, self.constants.smcspoof_path, lambda: self.constants.allow_oc_everywhere is False and self.constants.serial_settings != "None"), # CPU patches - ("AppleMCEReporterDisabler.kext", self.constants.mce_version, self.constants.mce_path, lambda: (self.model.startswith("MacPro") or self.model.startswith("Xserve")) and self.constants.serial_settings != "None"), ("AAAMouSSE.kext", self.constants.mousse_version, self.constants.mousse_path, lambda: smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value), ( "telemetrap.kext", @@ -167,6 +166,16 @@ class BuildOpenCore: # Required for Lilu in 11.0+ self.config["Kernel"]["Quirks"]["DisableLinkeditJettison"] = True + if self.constants.serial_settings != "None": + # AppleMCEReporter is very picky about which models attach to the kext + # Commonly it will kernel panic on multi-socket systems, however even on single-socket systems it may cause instability + # To avoid any issues, we'll disable it if the spoof is set to an affected SMBIOS + affected_smbios = ["MacPro6,1", "MacPro7,1", "iMacPro1,1"] + if self.model not in affected_smbios: + # If MacPro6,1 host spoofs, we can safely enable it + if self.constants.override_smbios in affected_smbios or generate_smbios.set_smbios_model_spoof(self.model) in affected_smbios: + self.enable_kext("AppleMCEReporterDisabler.kext", self.constants.mce_version, self.constants.mce_path) + if self.constants.fu_status is True: # Enable FeatureUnlock.kext self.enable_kext("FeatureUnlock.kext", self.constants.featureunlock_version, self.constants.featureunlock_path) diff --git a/resources/installer.py b/resources/installer.py index 0004e4922..a79b5daa7 100644 --- a/resources/installer.py +++ b/resources/installer.py @@ -187,6 +187,7 @@ def only_list_newest_installers(available_apps): for version in supported_versions: remote_version_minor = 0 remote_version_security = 0 + os_builds = [] # First determine the largest version for ia in available_apps: @@ -221,13 +222,25 @@ def only_list_newest_installers(available_apps): remote_version.pop(0) if int(remote_version[0]) < remote_version_minor: available_apps.pop(ia) - elif int(remote_version[0]) == remote_version_minor: + continue + if int(remote_version[0]) == remote_version_minor: if len(remote_version) > 1: if int(remote_version[1]) < remote_version_security: available_apps.pop(ia) + continue else: if remote_version_security > 0: available_apps.pop(ia) + continue + + # Remove duplicate builds + # ex. macOS 12.5.1 has 2 builds in the Software Update Catalog + # ref: https://twitter.com/classicii_mrmac/status/1560357471654379522 + if available_apps[ia]["Build"] in os_builds: + available_apps.pop(ia) + continue + + os_builds.append(available_apps[ia]["Build"]) return available_apps @@ -372,6 +385,13 @@ def generate_installer_creation_script(tmp_location, installer_path, disk): if utilities.check_filesystem_type() != "apfs": # HFS+ disks do not support CoW args[1] = "-R" + # Ensure we have enough space for the duplication + space_available = utilities.get_free_space() + space_needed = Path(ia_tmp).stat().st_size + if space_available < space_needed: + print("Not enough free space to create installer.sh") + print(f"{utilities.human_fmt(space_available)} available, {utilities.human_fmt(space_needed)} required") + return False subprocess.run(args) # Adjust installer_path to point to the copied installer diff --git a/resources/os_probe.py b/resources/os_probe.py index 79b3a4e04..545bdd05b 100644 --- a/resources/os_probe.py +++ b/resources/os_probe.py @@ -19,4 +19,4 @@ def detect_kernel_minor(): def detect_kernel_build(): # Return OS build # Example Output: 21A5522h (string) - return subprocess.run("sw_vers -buildVersion".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode().strip() + return subprocess.run("sw_vers -buildVersion".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode().split("\n")[0] diff --git a/resources/utilities.py b/resources/utilities.py index 8e5f5d89a..11eeef612 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -13,6 +13,7 @@ from ctypes import CDLL, c_uint, byref import time import atexit import requests +import shutil from resources import constants, ioreg from data import sip_data, os_data @@ -549,6 +550,11 @@ def find_disk_off_uuid(uuid): pass return None +def get_free_space(disk=None): + if disk is None: + disk = "/" + total, used, free = shutil.disk_usage("/") + return free def grab_mount_point_from_disk(disk): data = plistlib.loads(subprocess.run(f"diskutil info -plist {disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())