Identity
| Part | GigaDevice GD25LQ128 (16 MiB / 128 Mbit, JEDEC ID 0xc8 0x60 0x18) |
| Role | Boot-stage SPI NOR — holds rk2aw at sector 64 and Megi U-Boot 2024.04 at sector 20480 |
| Bus / address | spi1 (chip-select 0) |
| GPIO / IRQ | none beyond spi1 CS |
| Datasheet | GD25LQ128E (GigaDevice) |
| Pine64 wiki | PinePhone Pro Hardware |
| Schematic | sheet 5 (spi1 + boot flash) |
Status — ◐ partial
The chip is physically present and U-Boot drives it just fine — stock FreeBSD’s mx25l(4) driver does not recognise the JEDEC ID, so probe fails and /dev/flash0 never attaches. The flash itself is fully populated with the working bootloader stack (flashed from postmarketOS on 2026-03-31 — see essay 02). patches/sys/dev/flash/mx25l.c.patch adds the one-line table entry; status is partial because the patch is in-tree but not yet hardware-verified on the bench. Until it boots and flashctl /dev/flash0 read 0 512 returns rk2aw bytes, falsifiable claims below remain unproven.
Driver
- Our tree:
patches/sys/dev/flash/mx25l.c.patch— current patch slot for the JEDEC table addition (entry to be merged:{ "GD25LQ128", 0xc86018, 16 * 1024 * 1024, 4096, ... }). - Linux mainline:
drivers/mtd/spi-nor/gigadevice.c - FreeBSD upstream:
sys/dev/flash/mx25l.c
mx25l(4) is FreeBSD’s catch-all SPI NOR driver — despite the Macronix-flavoured name it handles Winbond, Spansion, Micron, and GigaDevice parts via a JEDEC ID lookup table. The probe sequence is RDID (0x9f) which returns three bytes: manufacturer (0xc8 for GigaDevice), memory type (0x60 for SPI NOR 1.8 V), capacity (0x18 for 128 Mbit). Without an entry in the table the driver logs an “unknown flash” error and detaches; nothing else uses the chip. After the table addition, 4 KiB sector erase plus dual-IO read should both work without further driver changes.
Open work
- Run the checked-in read-only verifier once the patched kernel is booted on the phone.
- Confirm endianness handling — the driver historically logged the ID byte-swapped on some platforms; current behaviour reports “0x25/0x7018” rather than the expected
0xc8 0x60 0x18. - Once
/dev/flash0is live, build a kernel-side workflow for in-place SPI updates so we don’t have to drop into postmarketOS to reflash U-Boot.
Parity verification
Once the patched kernel boots on the phone, the following checks prove the table entry took effect:
-
One-command verifier. Run:
mise run debug:spi-flash:phoneThe helper is read-only. It prints recent
mx25l/flash0dmesg lines, verifies/dev/flash0exists, reads 512 bytes from the rk2aw/idbloader offset (0x8000) and the U-Boot FIT offset (0xa00000), prints SHA256 plus a short hexdump for both, rejects an all-zero rk2aw probe, and requires FIT magicd0 0d fe edat the U-Boot offset. OverrideFLASH_DEV,READ_SIZE,IDB_OFFSET, orUBOOT_OFFSETonly if the boot layout changes. -
Attach line. dmesg should print something like
flash0: <GD25LQ128, 16MB, 4096 sectors of 4 KB each>(themx25l(4)attach format) at boot. No attach line → JEDEC ID lookup still fails. -
rk2aw header at sector 64.
flashctl /dev/flash0 read 0 512 | xxd | headshould show non-zero contents at offset0x8000(sector 64 × 512). Per essay 02, that’s whereidbloader.binwasdd’d on 2026-03-31. The Rockchip BootROM expects the rk2aw signature at this offset; if it’s there, the bootloader is intact and the read path works. -
U-Boot blob at sector 20480.
flashctl /dev/flash0 read 0xa00000 512 | xxd | headshould show the FIT image header (d0 0d fe eddevice-tree magic, since U-Boot uses a FIT/DTB-style container) at offset0xa00000(sector 20480 × 512). Cross-references essay 02’s flashing recipe. -
Falsify. If the kernel logs any other manufacturer ID (e.g.
0x25/0x7018, the historical byte-swap symptom) — or attaches with a wrong size / wrong sector count — the table entry is wrong and the patch needs revisiting. A successful attach with all-zero reads at the rk2aw offset would mean the chip is recognised but the bootloader is gone, which contradicts essay 02 and would warrant a re-flash before declaring the driver fix bad.
Related
- Boot from SD with Honeyguide — this flash holds the bootloader that reads the SD card.
- Internal eMMC, microSD slot — the storage targets the bootloader hands off to.
- Hardware reference — full chip manifest.