Add Linux host support for firmware prep, and silence two harmless boot-noise sources - #1
Open
cn0xroot wants to merge 1 commit into
Open
Add Linux host support for firmware prep, and silence two harmless boot-noise sources#1cn0xroot wants to merge 1 commit into
cn0xroot wants to merge 1 commit into
Conversation
get_files.sh / fix_perms.sh can now run on Linux, not just macOS: a new dmgutil.sh wraps DMG mount/copy so the ramdisk-patching and permission-fixing steps go through the linux-apfs-rw kernel module + ldid on Linux, while continuing to use hdiutil/ditto/codesign unchanged on macOS. See LINUX.md / LINUX.zh-CN.md for setup and rationale. Also patches out two console-spam sources that show up regardless of host OS, since this VM never emulates a SEP or provides a real dyld shared cache: dt_fixup.py removes the device tree's 'sep' node (stops AppleCredentialManager's infinite SEP-wait retry loop), and the new patch_bootkc.py truncates an unconditional shared_region check_np() debug string in bootkc (1-byte data patch, no instruction changes).
phakoda
added a commit
to phakoda/darwin-vm
that referenced
this pull request
Aug 31, 2026
Port the firmware-prep pipeline to Linux using linux-apfs-rw for the APFS recovery ramdisk and ldid for ad-hoc signing/CDHash extraction. Keep the existing macOS hdiutil/ditto/codesign path unchanged. Based on the Linux-host implementation and end-to-end testing from jprx#1, rebased onto the current main without importing its unrelated guest SEP/kernelcache noise patches.
d0lb33
added a commit
to d0lb33/darwin-vm
that referenced
this pull request
Sep 2, 2026
Two results, both from the full four-feature boot that only became possible today. The idle is named. Every SpringBoard thread is asleep: three blocked in ipc_mqueue_receive_results on distinct empty Mach receive queues, the fourth parked in workq_unpark_continue, with the continuation unslid to 0xfffffff00afb0b48 and matched against osfmk/ipc/ipc_mqueue.h:122 and osfmk/kern/waitq.h:198. Nothing is spinning or crashed -- they are waiting for messages that never arrive. Thread addresses, states, continuations and wait queues are in docs/re/boot-idle.md. The inbound callback direction now works end to end, which was the named display gate: iomfb: ep 0x37 callback jprx#1 'D575' (0x44353735) in 88 out 76 -> heap+0x40000 iomfb: IOP -> AP ep 0x37 0x000000b000000302 (class-2 callback 'D575') iomfb: ep 0x37 class 2 subkind 1 (callback completion) tag 0 ack 1 status 0x0 The hot-plug-shaped D575 executes and returns status zero, and userspace opens IOMobileFramebufferUserClient for the first time. The display hypothesis is now qualified rather than confirmed: DCP is on the SpringBoard path, but it is not sufficient. A385 returning 1 stops 5,442 polls (down to 3) without preventing the failure, and SpringBoard still exits with DCP fully active. The RAM snapshot carries no usable OS_REASON or exception codes, so the exit cause is left unnamed rather than guessed -- the apparent backtraces decode as TASK_CRASHINFO_UDATA_PTRS, opaque user-data pointers, not instruction addresses. Regression probes preserve both invariants: 11/11 AFK endpoints, and default-off boots unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
get_files.sh/fix_perms.shcan now run on a Linux host, not justmacOS. The macOS path is untouched — every new branch is gated behind
[[ "$(uname)" == "Darwin" ]], so this is purely additive.this VM never emulates a SEP or a real dyld shared cache) are now
silenced, without touching any code logic.
See
LINUX.md(English) /LINUX.zh-CN.md(Chinese) for the full writeup —extra host dependencies, exactly what changed and why, and the patch
rationale.
CHANGELOG.mdhas a shorter changelog-style summary.Motivation
The README's setup steps for downloading/patching firmware
(
get_files.sh'spatch_ramdisk, andfix_perms.sh) shell out tomacOS-only tools (
hdiutil,ditto,codesign) and just print "you need aMac" and exit on any other OS. Building
qemu-sptmitself already worksfine on Linux (the README already says the build/run machine "can be
different" from the Mac used for firmware prep) — this PR closes the last
gap so the entire pipeline, prep included, works on Linux too.
What changed
dmgutil.sh: shared helpers (dmg_attach,dmg_detach,copy_tree) for mounting/unmountingramdisk.dmgand copying directorytrees into it. On macOS these are thin, behavior-preserving wrappers over
hdiutil/ditto. On Linux:out-of-tree kernel module, since
firmware/ramdisk.dmgturns out to be araw APFS container image (no UDIF/HFS+ wrapper) —
mount -t apfs -o loop,readwrite[,uid=…,gid=…]works directly on it.cp -a --remove-destination— the Linux apfs driver'sexperimental write support doesn't implement
O_TRUNC, so overwritingan existing file has to unlink-then-create rather than
truncate-in-place, or
cpfails with "Operation not supported".get_files.sh/fix_perms.sh: sourcedmgutil.sh; no longer bailout on non-Darwin hosts; use
ldid -Cadhoc -S/ldid -hin place ofcodesign -s -/codesign -d -vvvon Linux (textually compatibleoutput, so the existing
grep -i cdhash=parsing needs no changes);chown root:wheelbecomeschown 0:0on Linux (same uid/gid pair — thewheelgroup is gid 0 on macOS, same as Linux'srootgroup).dt_fixup.py: removes the device tree'ssepnode and setssepfw-load-at-boot=0. Without this,AppleCredentialManagerbelieves aSEP is present and retries forever, printing
ACMTRM: waitForSEPEndpoint: timed out waiting for AppleSEPManagerevery ~5 seconds for the entirelife of the VM.
patch_bootkc.py, wired intoget_files.sh'smain()rightafter
bootkcis downloaded: truncates an unconditionally-printedshared_region: ... check_np(...) vm_shared_region_start_address() returned 0x1debug format string in place, by overwriting its first bytewith a NUL. This message otherwise reprints on every single process
launch in the guest. The patch is a single data byte, zero instruction
changes (printf-family functions never read their vararg list when the
format string has no
%directives), and was verified byte-identicalagainst both an iOS (
iPhone17,3) and macOS (Mac16,10)bootkc.run.sh: addedtrm_enabled=0 hidrm_enabled=0toBOOT_ARGSas asecondary, harmless mitigation alongside the device-tree fix for the SEP
retry noise (kept even though it alone wasn't sufficient to stop it).
.gitignore: excludes generated/downloaded output (firmware/,ipsw_db/,sysroot/,sysroot.tar.gz,mnt/,qemu-sptm/build/).Testing done
On a Linux host (Ubuntu 24.04, kernel 7.0.0-30-generic, x86_64):
ipswandldidfrom source, andlinux-apfs-rwagainst therunning kernel's headers.
get_files.sh→fix_perms.sh→run.shpipelineend-to-end for both an iOS guest (
iPhone17,3) and a macOS guest(
Mac16,10), each booting cleanly to a root shell with commands (id,whoami,uname -a,ls) returning correct output.multiple repeated boots on both device targets.
identical to what it was before this PR (same
hdiutil/ditto/codesigninvocations, same flags), so no regression is expected there.
Notes for reviewers
device tree / kernelcache, not anything host-specific), so they're worth
taking independently of the Linux-hosting changes if preferred.
linux-apfs-rw's write support is explicitly labeled experimentalupstream. It's been reliable in all testing here (building/rebuilding
firmware for two different device targets, repeatedly), but flagging it
since it's the one new moving part with a "use with caution" label from
its own author.