USB link
The kernel's console and command channel over USB, and the host tool that talks to it.
The phone has no serial port to reach. The USB link is how a development build gives its console and takes commands: a vendor-class USB device that mapple-link.py on the Mac talks to. It is how every
run is read and steered.
Turning it on
The boot-argument mp_usblink (see the catalogue): 0 off (the default), 1 probe the USB controller, 2 probe, then panic with the summary, 3 start the Mapple link.
The link and its commands are development tools: a RELEASE kernel has none. The single-boot layout’s line sets mp_usblink=0.
On the wire the phone is 1209:0002 “Mapple link” (the persona link), or, once the user-space daemon mapple-usbd switches it, 05ac:12a8 (the persona std: PTP, usbmux and the link as one more interface).
The host tool claims only the link interface. mp_usblink_std=0 keeps the phone in its own persona. The link counts as active only while the host sends its heartbeat (a vendor request every second, a 4 s timeout); only
then does the charger keep the 500 mA USB input limit.
The host tool
tools/mapple-link.py of mapple_build needs pyusb and libusb (brew install libusb, python3 -m pip install pyusb) and textual for the full-screen interface.
| Command | What |
|---|---|
mapple-link.py | the full-screen interface: a command prompt, the command output and the phone’s log |
mapple-link.py [-o LOGFILE] log | the live console only (-t puts the Mac’s time on each line, for boot timings) |
mapple-link.py cmd COMMAND... | send one command, print the reply, exit |
mapple-link.py dump PA SIZE FILE | save physical memory (through peek) to a file |
mapple-link.py dumpdtb [FILE] | save LK’s merged device tree |
mapple-link.py push LOCAL PATH [MODE], pull PATH [LOCAL] | copy a file to or from the phone, checked by FNV-1a |
mapple-link.py run PROGRAM [ARGS..] | run a program through mappled and print its output |
mapple-link.py bootrec [hex|show] | edit the boot-args record in your editor |
The interface reattaches when the phone re-enumerates (a persona switch or a reboot).
Commands on the phone
One command per packet, as text. help on the phone lists the arguments.
| Command | What |
|---|---|
ping, stat, help | liveness; uptime, link and log counters |
peek PA [WORDS], poke PA VALUE | read 32-bit words of physical memory or MMIO (at most 64); write one and read it back. No guard: an address in a gated block can hang the bus |
pmic ADDR [N] | read PMIC registers through the wrapper (read only) |
i2c DEV REG N, i2cw, i2c8 BUS DEV REG N, i2c8w | read and write bytes on the I2C buses |
bat, wifi, bt, torch, touch, gpu, cpu, disp | each driver’s status and its subcommands: the subsystem pages say what each has |
push, pull, run, mappled | files and programs |
rewind [BYTES] | resend the log from some bytes back |
console [on|off] | kernel text on the screen |
panic [TEXT], reboot | test the panic path; a watchdog software reset |
From user space kern.mapple_link gives a read-only subset of these to everyone and some more to root (Sysctls).
Frames from the phone are typed: L console log, R and E a command’s reply and its end, F file data, O the output of a program mappled runs.
Source: bsd/dev/usb_link.c of the kernel at dcb77a0; tools/mapple-link.py of mapple_build at f7431bb.
Applies to Release 1, development builds · Updated 15 November 2026