Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Monterey Bluetooth Support #492

Merged
merged 9 commits into from
Sep 18, 2021
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
21 changes: 19 additions & 2 deletions Resources/Build.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,25 @@ def amd_patch(self, backlight_path):

self.config["DeviceProperties"]["Add"][tb_device_path] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000")}

# Bluetooth Detection
if not self.constants.custom_model and self.computer.bluetooth_chipset:
if self.computer.bluetooth_chipset == "BRCM2070 Hub":
print("- Enabling Bluetooth BRCM2070 for macOS Monterey")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2070_patch"
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
elif self.computer.bluetooth_chipset == "BRCM2046 Hub":
print("- Enabling Bluetooth BRCM2046 for macOS Monterey")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2046_patch"
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
elif self.model in ModelArray.Bluetooth_BRCM2070:
print("- Enabling Bluetooth BRCM2070 for macOS Monterey")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2070_patch"
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
elif self.model in ModelArray.Bluetooth_BRCM2046:
print("- Enabling Bluetooth BRCM2046 for macOS Monterey")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2046_patch"
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)

# Add XhciDxe if firmware doesn't have XHCI controller support and XCHI controller detected
# TODO: Fix XhciDxe to work on pre UEFI 2.0 Macs
# Ref: https://github.com/acidanthera/bugtracker/issues/1663
Expand Down Expand Up @@ -697,7 +716,6 @@ def amd_patch(self, backlight_path):
print("- Allowing FileVault on Root Patched systems")
self.get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.filesystems.apfs")["Enabled"] = True


def set_smbios(self):
spoofed_model = self.model
if self.constants.override_smbios == "Default":
Expand Down Expand Up @@ -847,7 +865,6 @@ def get_efi_binary_by_path(self, bundle_path, entry_location, efi_type):
print(f"- Could not find {efi_type}: {bundle_path}!")
raise IndexError
return efi_binary


def enable_kext(self, kext_name, kext_version, kext_path, check=False):
kext = self.get_kext_by_bundle_path(kext_name)
Expand Down
7 changes: 6 additions & 1 deletion Resources/Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
self.featureunlock_version = "1.0.3" # FeatureUnlock
self.debugenhancer_version = "1.0.4" # DebugEnhancer
self.cpufriend_version = "1.2.4" # CPUFriend
self.bluetool_version = "2.6.1" # BlueToolFixup

## Apple
## https://www.apple.com
Expand Down Expand Up @@ -325,6 +326,10 @@ def featureunlock_path(self):
def debugenhancer_path(self):
return self.payload_kexts_path / Path(f"Acidanthera/DebugEnhancer-v{self.debugenhancer_version}.zip")

@property
def bluetool_path(self):
return self.payload_kexts_path / Path(f"Acidanthera/BlueToolFixup-v{self.bluetool_version}.zip")

@property
def innie_path(self):
return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}.zip")
Expand Down Expand Up @@ -653,7 +658,7 @@ def legacy_wifi_libexec(self):
"j215ap", # MacBookPro16,4
"j185ap", # iMac20,1
"j185fap", # iMac20,2
#"x86legacy", # non-T2 Macs/VMs, Monterey's boot.efi enforces this on all Macs
# "x86legacy", # non-T2 Macs/VMs, Monterey's boot.efi enforces this on all Macs
]

sandy_board_id = [
Expand Down
47 changes: 45 additions & 2 deletions Resources/ModelArray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,8 +1146,8 @@
"iMac12,2",
"MacPro3,1",
"MacPro4,1",
"XServer2,1",
"XServer3,1",
"XServe2,1",
"XServe3,1",
]

dGPU_switch = [
Expand All @@ -1165,3 +1165,46 @@
"MacBookPro16,1",
"MacBookPro16,4",
]

Bluetooth_BRCM2046 = [
"MacBook4,1",
"MacBook5,1",
"MacBook5,2",
"MacBookAir2,1",
"MacBookAir3,1",
"MacBookAir3,2",
"MacBookPro4,1",
"MacBookPro5,1",
"MacBookPro5,2",
"MacBookPro5,3",
"MacBookPro5,4",
"MacBookPro5,5",
"MacBookPro7,1",
"Macmini3,1",
"iMac8,1",
"iMac9,1",
"iMac10,1",
"iMac11,1",
"iMac11,2",
"iMac11,3",
"iMac12,1",
"iMac12,2",
"MacPro4,1",
"MacPro5,1",
]

Bluetooth_BRCM2070 = [
"MacBook6,1",
"MacBook7,1",
"MacBookAir4,1",
"MacBookAir4,2",
"MacBookPro6,1",
"MacBookPro6,2",
"MacBookPro8,1",
"MacBookPro8,2",
"MacBookPro8,3",
"Macmini4,1",
"Macmini5,1",
"Macmini5,2",
"Macmini5,3",
]
2 changes: 1 addition & 1 deletion Resources/Utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def download_file(link, location):
def enable_apfs(fw_feature, fw_mask):
fw_feature |= 2 ** 19
fw_mask |= 2 ** 19

return fw_feature, fw_mask

# def menu(title, prompt, menu_options, add_quit=True, auto_number=False, in_between=[], top_level=False):
# return_option = ["Q", "Quit", None] if top_level else ["B", "Back", None]
Expand Down
11 changes: 11 additions & 0 deletions Resources/device_probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class Computer:
cpu: Optional[CPU] = None
oclp_version: Optional[str] = None
opencore_version: Optional[str] = None
bluetooth_chipset: Optional[str] = None

@staticmethod
def probe():
Expand All @@ -324,6 +325,7 @@ def probe():
computer.storage_probe()
computer.smbios_probe()
computer.cpu_probe()
computer.bluetooth_probe()
return computer

def gpu_probe(self):
Expand Down Expand Up @@ -437,3 +439,12 @@ def cpu_probe(self):
subprocess.run("sysctl machdep.cpu.brand_string".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip(),
subprocess.run("sysctl machdep.cpu.features".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip().split(" "),
)

def bluetooth_probe(self):
usb_data: str = subprocess.run("system_profiler SPUSBDataType".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
if "BRCM2070 Hub" in usb_data:
self.bluetooth_chipset = "BRCM2070 Hub"
elif "BRCM2046 Hub" in usb_data:
self.bluetooth_chipset = "BRCM2046 Hub"
elif "Bluetooth":
self.bluetooth_chipset = "Generic"
20 changes: 19 additions & 1 deletion payloads/Config/config.plist
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,25 @@
<key>MaxKernel</key>
<string></string>
<key>MinKernel</key>
<string>20.4.0</string>
<string>16.0.0</string>
<key>PlistPath</key>
<string>Contents/Info.plist</string>
</dict>
<dict>
<key>Arch</key>
<string>x86_64</string>
<key>BundlePath</key>
<string>BlueToolFixup.kext</string>
<key>Comment</key>
<string>Fix Monterey Bluetooth</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
<string>Contents/MacOS/BlueToolFixup</string>
<key>MaxKernel</key>
<string></string>
<key>MinKernel</key>
<string>21.0.0</string>
<key>PlistPath</key>
<string>Contents/Info.plist</string>
</dict>
Expand Down
Binary file not shown.
42 changes: 42 additions & 0 deletions payloads/Kexts/Acidanthera/BlueToolFixup.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
diff --git a/BrcmPatchRAM/BlueToolFixup.cpp b/BrcmPatchRAM/BlueToolFixup.cpp
index 0fa891a..819eb3f 100644
--- a/BrcmPatchRAM/BlueToolFixup.cpp
+++ b/BrcmPatchRAM/BlueToolFixup.cpp
@@ -50,7 +50,15 @@ bool BlueToolFixup::start(IOService *provider) {
static const uint8_t kSkipUpdateFilePathOriginal[] = "/etc/bluetool/SkipBluetoothAutomaticFirmwareUpdate";
static const uint8_t kSkipUpdateFilePathPatched[] = "/System/Library/CoreServices/boot.efi";

+static const uint8_t kBluetoothUSBNameOriginal[] = "Bluetooth USB Host Controller";
+static const uint8_t kBluetoothUSBNamePatched2070[] = "BRCM2070 Hub Host Controller";
+static const uint8_t kBluetoothUSBNamePatched2046[] = "BRCM2046 Hub Host Controller";
+
static const char *blueToolPath = "/usr/sbin/BlueTool";
+static const char *bluetoothdPath = "/usr/sbin/bluetoothd";
+
+static const char brcm2046_patch = checkKernelArgument("-brcm2046_patch");
+static const char brcm2070_patch = checkKernelArgument("-brcm2070_patch");

static mach_vm_address_t orig_cs_validate {};

@@ -71,8 +79,19 @@ static void patched_cs_validate_page(vnode_t vp, memory_object_t pager, memory_o
char path[PATH_MAX];
int pathlen = PATH_MAX;
FunctionCast(patched_cs_validate_page, orig_cs_validate)(vp, pager, page_offset, data, validated_p, tainted_p, nx_p);
- if (vn_getpath(vp, path, &pathlen) == 0 && UNLIKELY(strcmp(path, blueToolPath) == 0)) {
- searchAndPatch(data, PAGE_SIZE, path, kSkipUpdateFilePathOriginal, kSkipUpdateFilePathPatched);
+ if (vn_getpath(vp, path, &pathlen) == 0) {
+ if (UNLIKELY(strcmp(path, blueToolPath) == 0)) {
+ searchAndPatch(data, PAGE_SIZE, path, kSkipUpdateFilePathOriginal, kSkipUpdateFilePathPatched);
+ }
+ if (UNLIKELY(strcmp(path, bluetoothdPath) == 0)) {
+ if (brcm2046_patch) {
+ DBGLOG(MODULE_SHORT, "Patching BRCM2046 Hub into bluetoothd");
+ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched2046);
+ } else if (brcm2070_patch) {
+ DBGLOG(MODULE_SHORT, "Patching BRCM2070 Hub into bluetoothd");
+ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched2070);
+ }
+ }
}
}