Skip to content

Commit 16f8428

Browse files
committed
stub: Collect non-iBoot FUD firmwares into all_firmware.tar.gz
Turns out we need these for Touch Bar, and for MTP on M2 machines... This also ends up collecting duplicate ANE>0 firmwares for some machines. That's probably a mistake in how Apple marked them in the config as non-iBoot, or just a sign that those ANEs are always disabled anyway, but let's not risk it by trying to filter them out... These are img4ps and need img4tool to extract. No proper parsing done yet, this is just the fallback path. Signed-off-by: Hector Martin <[email protected]>
1 parent cf96244 commit 16f8428

1 file changed

Lines changed: 35 additions & 2 deletions

File tree

src/stub.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ def install_files(self, cur_os):
113113
bootcaches = plistlib.load(ipsw.open("usr/standalone/bootcaches.plist"))
114114
self.flush_progress()
115115

116+
self.manifest = manifest
116117
for identity in manifest["BuildIdentities"]:
117118
if (identity["ApBoardID"] != f'0x{self.sysinfo.board_id:02X}' or
118119
identity["ApChipID"] != f'0x{self.sysinfo.chip_id:04X}' or
@@ -126,6 +127,7 @@ def install_files(self, cur_os):
126127

127128
logging.info(f'Using OS build {identity["Info"]["BuildNumber"]} for {self.sysinfo.device_class}')
128129

130+
self.all_identities = manifest["BuildIdentities"]
129131
manifest["BuildIdentities"] = [identity]
130132

131133
self.stub_info.update({
@@ -285,6 +287,35 @@ def collect_firmware(self, pkg):
285287
p_progress("Collecting firmware...")
286288
logging.info("StubInstaller.collect_firmware()")
287289

290+
logging.info("Collecting FUD firmware")
291+
os.makedirs("fud_firmware", exist_ok=True)
292+
copied = set()
293+
for identity in self.all_identities:
294+
if (identity["Info"]["RestoreBehavior"] != "Erase" or
295+
identity["Info"]["Variant"] != "macOS Customer"):
296+
continue
297+
device = identity["Info"]["DeviceClass"]
298+
if not device.endswith("ap"):
299+
continue
300+
device = device[:-2]
301+
for key, val in identity["Manifest"].items():
302+
if key in ("BaseSystem", "OS", "Ap,SystemVolumeCanonicalMetadata",
303+
"StaticTrustCache", "SystemVolume"):
304+
continue
305+
path = val["Info"]["Path"]
306+
if (not val["Info"].get("IsFUDFirmware", False)
307+
or val["Info"].get("IsLoadedByiBoot", False)
308+
or val["Info"].get("IsLoadedByiBootStage1", False)
309+
or not path.endswith(".im4p")):
310+
continue
311+
if path not in copied:
312+
self.extract(path, "fud_firmware")
313+
copied.add(path)
314+
fud_dir = os.path.join("fud_firmware", device)
315+
os.makedirs(fud_dir, exist_ok=True)
316+
os.symlink(os.path.join("..", path),
317+
os.path.join(fud_dir, key + ".im4p"))
318+
288319
img = os.path.join(self.osi.recovery, self.osi.vgid,
289320
"usr/standalone/firmware/arm64eBaseSystem.dmg")
290321
logging.info("Attaching recovery ramdisk")
@@ -294,8 +325,10 @@ def collect_firmware(self, pkg):
294325
col = firmware.wifi.WiFiFWCollection("recovery/usr/share/firmware/wifi/")
295326
pkg.add_files(sorted(col.files()))
296327
logging.info("Making fallback firmware archive")
297-
subprocess.run(["tar", "czf", "all_firmware.tar.gz", "-C",
298-
"recovery/usr/share", "firmware"], check=True)
328+
subprocess.run(["tar", "czf", "all_firmware.tar.gz",
329+
"fud_firmware",
330+
"-C", "recovery/usr/share", "firmware",
331+
], check=True)
299332
self.copy_idata.append(("all_firmware.tar.gz", "all_firmware.tar.gz"))
300333
logging.info("Detaching recovery ramdisk")
301334
subprocess.run(["hdiutil", "detach", "-quiet", "recovery"])

0 commit comments

Comments
 (0)