Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/saf/device/platform.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

6.2 KiB

PAF · Platform — hardware, boot, storage, recovery (Arch era)

Load-bearing device facts. Add a line when something costs more than 2 minutes to relearn. pmOS-era snapshot preserved at evidence/platform-pmos-era.md — its Alpine/ash and pmOS-slot notes no longer apply.

Reaching the phone

  • USB (primary): ssh -F /dev/null -i ~/.ssh/ani -o BatchMode=yes casey@172.16.42.1 (NCM gadget, phone serves DHCP; laptop autoconfigures).
  • WiFi: DHCP on the LAN, drifts — check the router or nmcli on-device via USB first.
  • User casey, passwordless-sudo NO — sudo password 147147 (echo 147147 | sudo -S <cmd>). Never stream sudo-gated output through further pipes over SSH (silent truncation, repeatedly) — write to a file on the phone, pull it separately.
  • Shell is bash on Arch (systemd, GNU coreutils, pacman). The pmOS-era busybox/ash caveats are dead.
  • Serial fallback: ACM gadget → laptop-side ttyACM0; getty enabled on ttyGS0.

Slots & boot architecture

  • Slot A = Arch (ours). Slot B = LineageOS (Android, rooted, on the 4.9 vendor kernel). Slot B is the living downstream reference AND the fallback OS — never touch boot_b or Android's partitions.
  • Boot chain: ABL boots boot_a (Android bootimg v0, our kernel Image.gz with appended DTB + the pmOS-chain ramdisk — see build.md). Root is found by UUID from the baked cmdline.
  • qbootctl (in the device package since ef21637) marks the slot successful and provides reboot-to-android; closes the A/B retry-lockout that used to eat boots.
  • Switch to Android: sudo reboot bootloaderfastboot --set-active=bfastboot reboot (and back with --set-active=a).

Storage (live table, verified on-device 2026-07-10)

UFS /dev/sda, GPT, 4096-byte sectors (sgdisk needs -a 256; a tool assuming 512B sectors will misread the table).

Part Size FS Name Role
sda21 42.9G userdata Android's, FBE-encrypted, NEVER TOUCH (near-formatted once — always verify identity before writing any partition)
sda22 10.0G fat32 shared Arch↔Android shared data, mounted /shared
sda23 253M vfat Arch_boot staging/aux boot filesystem
sda24 66.2G ext4 Arch_root the Arch rootfs, UUID=a094e031-ea89-4847-a299-082a0ae8c9ab

persist lives on a different UFS LUN (sdf2) — physically immune to sda operations; mounted ro,nofail. Backup in ../blobs/ + ~/pixel3-backup/persist.img.

  • Boot-image A/B slots (boot_a/boot_b, 67MB each, partitions 11/12) are separate from the rootfs partitions above — fastboot flash boot_a is the only flash operation this project performs.

Recovery

  • TWRP: fastboot boot ~/Downloads/twrp-3.7.1_12-0-blueline.img (boot, not flash). Used for repartition-class work; a live pmOS/Arch root can't modify its own mounted partitions.
  • Known-good fallback kernel image (stmfts touch, pre-SWIRE display): ../staging/deploy-139aa/boot-139aa7748181-pmoschain.img → flash to boot_a. Its module tree is on the phone.
  • Full stock partition clone (2026-06-18) at ~/pixel3-backup/; LOS boot image at ~/Downloads/lineage-22.2-20260629-boot.img.
  • Last resort: slot B is a complete, working Android.

Hardware map (what's proven on this exact unit)

  • SoC sdm845, 4G RAM. Panel: LG SW43408 (DSC command-mode, 1080x2160) — settled from per-unit persist calibration data; the Samsung s6e3ha8/sec_ts DTBO fragments are the OTHER hardware variant, not ours.
  • Touch: ST FTS @ 0x49 on i2c-2 (888000 geni SE, GPI-DMA-only); reset tlmm 99 (active-low RESETB), IRQ tlmm 125, AP/SLPI bus switch tlmm 136.
  • OLED bias: PMI8998 LAB/IBB under SWIRE (DDIC hardware) control — see display.md.
  • WiFi wcn3990 (ath10k_snoc), BT (hci_uart/btqca), modem MPSS (see modem.md), sensors behind SLPI DSP (see slpi.md), audio WCD9340 over SLIMbus (working HiFi speaker, microphone and two-way calls; see audio.md).
  • Power button = pm8941_pwrkey → input event; volume keys GPIO.

Charging (pmi8998, qcom_smbx)

Two supplies: pmi8998-charger (the charger) and qcom-battery (fuel gauge). The charger IC does full CC/CV — trickle, pre, fast, full-on, taper — and BATTERY_CHARGER_STATUS_1 bits 0:2 report which stage it is in. Mainline read that register only to derive status, collapsing all five states into "Charging" and discarding the detail.

Since f08dc70b3 the driver exposes them:

attribute register notes
charge_type BATTERY_CHARGER_STATUS_1 (0x06) read-only; Trickle/Fast/Standard
constant_charge_current_max FAST_CHARGE_CURRENT_CFG (0x61) 25000µA/step, 8-bit
voltage_max FLOAT_VOLTAGE_CFG (0x70) raw=(uV-3487500)/7500+1; 4.4V → 122
charge_control_end_threshold same as above percentage form, 0-100

Lowering the float voltage is what caps the charge. The cell is held at whatever CV target is programmed, so 4.1V parks it near 80% and buys calendar life. Writes are bounded twice — by the DT cell rating (voltage-max-design-microvolt = <4400000> in sdm845-google-blueline.dts) and by what the 8-bit fields can encode, so neither an overcharge nor a silent masked-off write is possible.

These registers are volatile — every setting is lost on reboot. Use /etc/blueline-charge-limit + blueline-charge-limit.service to persist one. Front end is blueline-charge status|limit|current.

Not exposed by this driver: charge_full/charge_now (fuel gauge, see qcom-battery) and any charge scheduling — downstream's google_charger ran a taper state machine with DT tunables (google,chg-itaper, chg-soctaper); mainline has no equivalent and this patch does not add one.

Hard lessons (each cost real time — do not relearn)

  • Verify partition identity before any write (parted -s /dev/sda print
    • blkid); an unlabeled lsblk row is not free space. The sda21 near-miss is the standing warning.
  • /tmp on the phone is tmpfs — never park artifacts there.
  • fastboot boot <img> has a ~60s hardware watchdog — flash, don't test-boot, anything that takes long to come up.
  • Trust the user's direct visual report of the glass over any remote telemetry — registers can say "on" while the panel shows black.