Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/tasks/64-one-iphone-build.md
Fimeg bde961c6f2 saf: one spine — device, state, and work under the index
PAF becomes saf/device (history kept), STATE.md dissolves
into saf/state.md with the dated era archived, the substrate
SAF moves up from souveraine, and every agreement points at
saf/INDEX.md and nowhere else. one map, nothing to remember
2026-08-18 09:47:30 -04:00

9.3 KiB

TASK 64 — one SouveraineOS build for the iPhone

Status: scoped 2026-08-10; repository foundation landed, build work not started. Casey, 2026-08-10: "we're going to OWN the PIPELINE from BOOT to OS. Gutting ALL the iBoot extra we don't need, Gutting all the hoolock whatever. I want ONE SOUVERAINEOS BUILD for the IPHONE." Repos: souveraine-iphone (the D10 boot path and device artifacts), Pixel3Arch, SouveraineOS.

souveraine-iphone was renamed from hoolock-d10 on 2026-08-10. Hoolock remains upstream bring-up provenance, not this project's identity.

TASK-63 made the d10 a body. This task makes it a build. Today the iPhone boots through a rescue-distro loader carrying an iPad's name, a kernel tree that is not a repository, and a laptop-side shell script — none of which is a package and none of which CI has ever built.

Why now

souveraine-iphone/ is the D10 project checkout. It still contains a vendored Hoolock rescue environment plus m1n1 plus pongoOS plus an IPSW scratch area. The parts we use are small:

kept what it does
remote_boot/remoteboot.sh checkm8 + patched iBSS, DFU → m1n1
m1n1-pauli the loader that knows D10's PCIe/S3E bootstrap
boot.sh stages, hands off, verifies
d10-port/ the DTS, firmware blobs, DELTAS

Everything else — HoolockRD, pongoOS, ipsw/, the rescue ramdisk, the tutorials — is bring-up scaffolding for a device that now boots off nvme0n1p1. docs/ is upstream Hoolock's, not ours.

The kernel tree is the sharper problem. linux-pauli lives on archdev, is not a git remote anywhere, and today carried nine dirty files with no commit. Its work reaches the phone by scp of Image.gz into souveraine-iphone/out/. That is the "second secret road to success" the working agreement forbids, and it is the only road this device has.

What one build has to answer

  1. The kernel is a package. linux-d10 built by CI, published to souveraine-aarch64, versioned so -Syu can upgrade it. Today it is a hand-built Image.gz and a .dtb copied to a laptop directory, picked by mtime.
  2. The tree has a home. linux-pauli is a fork of Pauli1Go/HoolockLinux with local commits. It needs a Gitea remote, a branch, and the d10 work committed — BOOT-d10.md already records that it "wants a real home", and saf/device/evidence/d10-adp-touch-2026-08-09.patch is the workaround.
  3. The loader is a package. m1n1 + the patched iBSS chain, versioned with the kernel it hands off to.
  4. One command boots her. boot.sh is good and stays; it should consume packaged artifacts instead of a staging directory only this laptop has.
  5. Gut the rest. Delete HoolockRD, pongoOS, ipsw/, docs/. Keep d10-port/, fw-docs/ (the firmware reproduction is real and cites hashes), BOOT-d10.md.
  6. The device identity is a package, per TASK-63's split: DTB, the nowifi variant, T8010 quirks, PHONE_HOST.

Measured 2026-08-10, so it is not re-derived

Display work happened today and produced facts worth more than the code did. All of the below is verified on hardware unless marked.

  • The raster is now derived, not guessed. Read off the DW-DSI host m1n1 programmed, via adp_mipi_regs:

    vid_pkt_size 750   vid_vactive_lines 1334
    vid_vfp_lines 504  vid_vsa_lines 3   vid_vbp_lines 4
    vid_hline_time 1332 byte-clocks = 888px x 1.5  (2 lanes, 24bpp)
    vid_hsa_time 48 -> 32px   vid_hbp_time 6 -> 4px   hfp -> 102px
    dpi_color_coding 5 = 24-bit RGB888
    

    So 888 x 1845 @ 60, 98301 kHz. TASK-63 named the invented timings as one of two candidates for the dark panel; they are no longer invented. The arithmetic closes exactly on 2 lanes / 24bpp, which also confirms the ADT's #lanes = 2. Nothing in Linux reprograms that host, so ADP's mode must match it.

  • aperture_remove_all_conflicting_devices() is the correct handoff. ADP calls it at bind and simpledrm goes away with no cmdline. boot.sh -a and initcall_blacklist=simpledrm_platform_driver_init become unnecessary; &framebuffer0 { status = "disabled" } stays useless because m1n1's kboot re-enables /chosen/framebuffer, but it no longer matters. Confirmed: drm : card1 alone, one writer, early boot console preserved.

  • The DART is fine. apple-dart 206304000.iommu: DART [pagesize 1000, 4 streams, AS 32 -> 36] initialized, 206200000.display-pipe: Adding to iommu group 0. m1n1's "dart is of an unknown type" is m1n1 declining to set it up, not Linux failing to. fb_base reading above the top of RAM is an iova and is expected. Ruled out.

  • panel-summit marks every panel non_desktop. Correct for a Touch Bar, wrong here — compositors skip such connectors. Gated on the match data.

  • The panel was dimmed to nothing and it hid everything else. Both backlights read 1600/2047 in the morning; by evening 206600000.dsi.0 read 20/2047 while 20e200080.backlight held 1474 — a lit backlight over a black panel. This is TASK-63:165 exactly: Dim is brightnessctl set 10, an absolute that is 0.5% of the iPhone's 2047-step scale. souveraine eb0292c fixes it and has still not shipped. Check both backlights before diagnosing any dark-panel symptom on this body.

  • ADP still shows nothing with everything else correct. Connector connected/enabled, derived mode in use, pix_fmt 0x053e4001, src/dst 0x02ee0536, scale_ctl bypass, blend enables set, adp-fe at exactly 60/s, backlights at 2047. modetest sets the mode without error and the panel blips. A CPU-written dumb BO does not appear either, so this is the kernel's buffer path and not the compositor.

  • The remaining delta, untested: the state m1n1 leaves working versus the state ADP writes.

    layer_ctl   0x01111001  ->  0x00010001    bits 24, 20, 12 dropped
    layer_en1   0x00001001  ->  0x00000001    bit 12 dropped
    blend_en2   0x00000000  ->  0x00000001
    mask_buf    0x001a0015  ->  0x00050000
    

    ADBE_LAYER_CTL_ENABLE | BIT(0) is a Touch Bar constant. mask_buf changes even when the driver stops writing it, so it is pipe state and not a pointer — that theory was wrong. A kernel preserving the layer_ctl/layer_en1 bits is built and staged as adp16 and has never been booted.

  • adp_drm_gem_dumb_create() never sets args->pitch, then computes size = pitch * height and calls drm_gem_dma_dumb_create_internal(), which — unlike drm_gem_dma_dumb_create() — does not compute one either. Reasoned, not tested.

  • Our adp_drv.c is mainline plus local diagnostics. Diffed against torvalds/linux: nothing removed, nothing drifted.

  • No prior art exists for this part. BOOT-d10.md:280 — both working T8010 ports (Pauli1Go/HoolockLinux on J172/D111, yhavry's D101) are simple-framebuffer only. Zero display/adp/panel/dsi commits across all four Pauli1Go repos. The only reference is HoolockLinux/linux 2b3b1a7fc "t8012 dts: display pipe", already used for the addresses. Nobody has run ADP on a T8010.

Separate and still unexplained: viewtop does not flip

Reproduced on simpledrm and on ADP, on the stock kernel and every patched one. fb_base does not change for 30 s; /dev/fb0 hashes byte-identical for 50 s; the control socket answers instantly and reports panel_pending: false; viewtop sits in do_epoll_wait and qs keeps burning ~1.5% CPU. The shell draws once and then no commit reaches the panel.

Do not read compositor CPU as evidence of drawing. The framebuffer hash is the signal; process state is not. That mistake cost most of an afternoon.

This is not a display-driver bug and will still be here when the panel lights. It is TASK-43/51's lane, on a body viewtop has never driven — before the d10, every panel viewtop had ever driven was blueline's.

Dead code to remove before any commit

drm_sysfb_modeset.c, drm_sysfb_helper.h, simpledrm.c and include/drm/adp_vblank.h carry a vblank-synced scanout blit: ADP publishes its 60 Hz edge, sysfb holds the commit until the raster is in the 504-line porch. It works and it is now unreachable — the aperture handoff removes simpledrm from the panel entirely. It cost a day and it does not ship.

The mechanism it found is still true and worth keeping in words: drm_sysfb_plane_helper_atomic_update() blits into live scanout with no fence, no vblank and no second buffer. That is what the tearing was, and it is why smithay's failed to create signaled syncobj was a symptom rather than a cause.

Acceptance

  • pacman -S installs the d10 kernel, DTB and loader as owned packages.
  • The kernel tree has a Gitea remote and the d10 commits are on a branch.
  • CI builds the kernel; no Image.gz reaches a phone by scp.
  • souveraine-iphone/ contains only what boots this device.
  • boot.sh consumes packaged artifacts, not out/.
  • A second T8010 joins by installing a package.

Connects to

TASK-63 (the body; this is its build), TASK-01 in Projects/Gitea Pipeline/ (one pipeline — this is its second device, and its evidence section still credits 72608e9 with fixing d10 tearing, which is wrong and wants correcting), TASK-25/27/28 (the overlay-vs-package hole), TASK-43/51 (viewtop; the flip stall), kernel-pipeline-blockers (kernel.yml has never gone green).