A hand built Debian arm64 system on a custom mainline 6.12 kernel running on the Samsung Galaxy S20 Ultra 5G (SM-G988B, codename z3s, Exynos 990 / exynos9830). It has a working display, an internal UFS root, multi touch, a GPU accelerated KDE Plasma desktop, and Wi-Fi with full WPA2 and internet.
This repository is the reproducible, shareable subset of that project: the drivers, patches, device tree, kernel config, build and flash tooling, desktop glue, and the full technical write ups. It exists because a lot of this had no prior mainline solution. The S2MPS19 PMIC over ACPM storage path, the onboard UFS quirk, the S2DOS05 touch power discovery, Mali G77 on Panfrost, and the BCM4375 host_cap Wi-Fi fix are all documented here end to end so nobody has to rediscover them.
This is not postmarketOS. pmOS, x1s, and c1s trees are used only as reference for driver and device tree patterns. Everything here is integrated by hand on the mainline tree.
No proprietary firmware or personal data is included. Broadcom and Samsung firmware, NVRAM, partition dumps, IMEI/EFS, and stock images are not in this repo. See firmware/ for how to extract what you need from your own device.
| Subsystem | Status | Key to making it work |
|---|---|---|
| Mainline 6.12 boot to systemd | working | custom kernel plus uniLoader plus initramfs |
| Display 1440x3200 (WQHD) | working | bootloader lit DECON framebuffer via simpledrm KMS |
| Display 120Hz (needs FHD 1080x2400) | in progress | live DECON/DSIM/DSC/panel reprogram, partial FHD@120 frames, see docs/DISPLAY.md |
| microSD storage | working | S2MPS19 PMIC over ACPM, backported from Google Tensor gs101 |
| Onboard UFS (128 GB) root | working | BROKEN_RX_SEL_IDX to TIMER_TICK_SELECT, 736 MB/s, first on this SoC |
| USB networking and SSH | working | composite RNDIS plus ACM gadget, the recovery path |
| Touchscreen (multi touch) | working | S2DOS05 display sub PMIC LDO2/LDO3 to mainline s6sy761 |
| GPU acceleration (Mali G77) | working | Panfrost plus Mesa G77 model, PAN_MESA_DEBUG=noafbc |
| KDE Plasma desktop | working | Plasma Wayland, GPU composited, HiDPI |
| Wi-Fi (BCM4375) | working | ported Exynos PCIe plus brcmfmac PCIe, host_cap fix, full WPA2 and internet |
| CPU DVFS (all 8 cores) | working | ACPM cpufreq driver, schedutil scaling, M5 prime cores re-enabled, first on this SoC |
| Battery and charging (MAX77705) | working | fuel gauge via mainline max17042, plus a backported max77705 charger; UI shows charge percentage and Charging status |
| Bluetooth (BCM4375) | working | BT over UART1 with hci_bcm; the USI needs the exynos-usi wrapper plus samsung,clkreq-on for UART Rx; hci0 comes up on boot |
| Audio (ABOX Calliope DSP) | in progress | DSP fully boots and runs its firmware, front-end pumps real samples, CS35L41 amps power up; blocked on the DSP-owned back-end serializers (needs the ABOX ASoC driver), see docs/AUDIO_DSP.md |
| Power-off / shutdown | working | clean power-cut via PS_HOLD 0x030C (PSCI SYSTEM_OFF hangs S-Boot) plus the S2MPS19 WTSR/SMPL watchdog cleared over ACPM before power-cut; the phone shuts down and stays off, see docs/POWEROFF.md |
| Power/lock button | working (soft sleep) | short press locks + toggles OLED DPMS; four-second hold opens Plasma shutdown/restart prompt; real suspend remains blocked by BCM4375 D3, see docs/POWERKEY.md |
| Development workstation | working | Git/toolchains/debuggers, Node 22, Pi Coding Agent, VS Code ARM64, Kitty/tmux/Neovim and health reporting; account/security phases remain, see docs/DAILY_DRIVER.md |
| Modem, cameras | not done | see docs/PORT.md |
The end result is a device that boots from internal UFS in about 4 seconds to a GPU accelerated, multi touch KDE Plasma desktop with internet over Wi-Fi, running all eight CPU cores with dynamic frequency scaling.
Storage via the PMIC. The SD and UFS rails hang off the S2MPS19 PMIC, which the CPU cannot address directly. The only path is AP -> AP2APM mailbox @0x15900000 -> APM (Cortex-M, ACPM firmware) -> SPEEDY bus -> S2MPS19. The gs101 ACPM stack (byte identical protocol, same SRAM base 0x2039000) was backported into 6.12. Detail in docs/session-findings/SESSION3_FINDINGS.md.
Onboard UFS root at 736 MB/s from a single exynos990_ufs_drvs flag fix. Detail in docs/session-findings/SESSION4_FINDINGS.md.
Touch power on the S2DOS05 display sub PMIC, not the main PMIC, on a second USI muxed I2C bus that had never been brought up. Detail in docs/TOUCH_S2DOS05_BREAKTHROUGH.md.
Mali G77 on Panfrost: the kernel model table, the G3D power domain fix, the Mesa model, and the AFBC workaround. Detail in docs/GPU_BRINGUP.md.
BCM4375 Wi-Fi: the Exynos PCIe host and brcmfmac PCIe backend were ported, then the real blocker turned out to be that mainline brcmfmac never advertises the firmware host_cap word, so rev-7 firmware withholds RX data DMA and the WPA handshake cannot start. One TCM write fixes it. Detail in docs/WIFI_BRINGUP.md.
CPU DVFS: mainline could not drive the Exynos 990 CPU frequency at all. The clusters ran at a fixed low boot clock, the scheduler treated all cores as equal, and the M5 prime cores had to be offlined to avoid stalls. Getting DVFS working meant unblocking the ACPM DVFS channel through several layers (an interrupt-mode channel gate, a wrong command field, and a queue-length-1 deadlock that stopped the command being sent), then writing a cpufreq driver and adding a scheduler capacity model. The result is all eight cores scaling from minimum to maximum under schedutil, with the prime cores back. Detail in docs/CPU_PERF_DVFS.md.
Audio DSP (in progress): the ABOX Calliope DSP fetches its firmware through a secure, write-locked SysMMU that a non-secure kernel cannot program. Rather than program it, we bypassed it: the SysMMU sits in pass-through, so injecting a page-table remap into the DSP's own boot (add 0x78000000 to its firmware page-table entries) makes the DSP fetch real firmware from 0xf8000000 with no secure write. The DSP now fully boots and runs its firmware (past a second wall, an EL1 SCTLR MMU-enable that trapped to EL2, now crossed via a secure ABOX-GIC init over an EL3 SMC), the audio front-end pumps real samples, and the CS35L41 speaker amps power up and are clocked. The remaining wall is that SIFS0/RDMA3/UAIF2 are DSP-managed back-end DAIs whose hw_params -> prepare -> trigger lifecycle cannot be driven by register/IPC pokes; the real path is the mainline exynos ABOX ASoC driver. Detail in docs/AUDIO_DSP.md.
docs/ All write-ups: DEVLOG, hardware map (PORT.md), Wi-Fi, GPU, touch,
the build and flash guide, and the raw per-session findings.
kernel/
patches/ Kernel source deltas (working-tree diff, Panfrost G77).
config/ Kernel .config used on the device.
dts/ Device tree: exynos990-z3s.dts plus exynos990 dtsi/pinctrl/clk/headers.
drivers/
wifi-brcmfmac/ Ported brcmfmac PCIe driver (pcie.c, s2mpu.c/.h, chip.c) plus patches
(including the host_cap fix) plus a build README.
pcie-exynos/ Ported Exynos9830/990 PCIe host-v0 controller.
acpm-pmic/ Backported ACPM mailbox plus S2MPS19 PMIC (the storage power stack).
Includes the z3s-patched exynos-acpm.c (power-off STOP plus WTSR/SMPL
watchdog disable), the pristine mainline copies (_ml_*), the ACPM
protocol and mailbox headers, and the exynos990-pmic-probe smoke test.
acpm-dvfs/ ACPM and mailbox drivers patched for CPU DVFS (poll-gate, qlen==1,
single-slot completion, INTMR1 mask, cmd[3]) plus a README.
cpufreq/ The exynos990-cpufreq driver (per-cluster policies, schedutil).
ufs-phy/ The exynos990 UFS PHY driver (phy-exynos990-ufs.c).
regulator-s2dos05/ The S2DOS05 display sub-PMIC regulator driver (touch power).
abox-dsp/ Calliope DSP bring-up module (SysMMU-bypass page-table injection,
boot instrumentation) plus a README. Audio is in progress.
prebuilt-modules/ The proven brcmfmac.ko (host_cap, clean build) and exynos990-cpufreq.ko.
mesa/ Mesa Panfrost G77 model patch.
bootloader/ uniLoader pack, deploy, and extract scripts.
rootfs/ Desktop glue: systemd units, greetd autologin, Plasma launchers, KWin rules,
and the phone-style power-key/soft-sleep daemon.
tools/ Boot image build and flash tooling (mkbootimg_*, flash_z3s.sh, extractors).
firmware/ How to extract BCM4375 firmware and NVRAM from your device (no blobs shipped).
Read docs/build-and-flash.md for the reproducible path from base tree through patches, config, device tree, build, uniLoader, flash, and Debian rootfs. Read docs/PORT.md for the full hardware map (chips, buses, addresses, per block status). Read docs/DEVLOG.md for the chronological history. The subsystem deep dives are WIFI_BRINGUP.md, GPU_BRINGUP.md, TOUCH_S2DOS05_BREAKTHROUGH.md, CPU_PERF_DVFS.md (the CPU DVFS and cpufreq bring-up), BLUETOOTH.md, DISPLAY.md (the FHD@120 mode-set), AUDIO_DSP.md (the ABOX Calliope DSP), POWEROFF.md, POWERKEY.md, and DAILY_DRIVER.md.
These patches and drivers sit on top of an exynos990-mainline 6.12 fork, itself derived from mainline Linux plus the upstreamed exynos990/z3s work. The full base tree is not vendored here because it is large and GPL, so clone it fresh. The S2MPS19/ACPM stack was backported from the gs101 support that landed upstream in 6.15 and later. See docs/build-and-flash.md for exact sources.
Only ever write lk3rd, boot, userdata, and the microSD. Writing S-Boot, PIT, modem, or efs will brick the device. Never publish efs, sec_efs, or IMEI data. Access is over USB (usb0 and serial), so keep it unmanaged so a bad rootfs or a Wi-Fi change can never lock you out. Never use /dev/mem for hardware experiments. Build gently and never use -j$(nproc).
Kernel and driver code here is derived from Linux and is GPL-2.0, see LICENSE. Documentation is shared under the same repo license for simplicity. Proprietary firmware is not included and is not covered by this license.
Personal partition dumps, extracted stock firmware, and Samsung stock images are deliberately excluded. This repo is the engineering work and its documentation, meant to help the next person.