embflash — an image put into a target#
embflash programs a firmware image into a target through the GDB remote
serial protocol. That one protocol reaches nearly every way of programming
a part: QEMU's gdbstub, OpenOCD, pyOCD, SEGGER's J-Link GDB server and the
Black Magic Probe all speak it. The server runs the part's flash algorithm.
embflash reads the image, erases and writes the flash, verifies it, and
can start the program. This page is the command reference.
Synopsis#
embflash IMAGE --gdb TARGET [--base ADDR] [--verify] [--run]
[--entry ADDR] [--vector-table ADDR] [--monitor CMD]...
[--dry-run] [--timeout SECONDS] [-v]
TARGET is where the server listens:
| Target | Reaches |
|---|---|
HOST:PORT |
a TCP port: OpenOCD's 3333, a J-Link GDB server's 2331, pyOCD's 3333 |
unix:PATH |
a Unix-domain socket, such as QEMU's -gdb chardev: |
serial:DEV[@BAUD] |
a serial line at BAUD (default 115200), such as the Black Magic Probe's GDB port |
Images#
| Image | Read as |
|---|---|
| ELF | its stored bytes at their load addresses, as embpack packs them; the entry point comes from the header |
.hex, .ihex |
Intel HEX (record types 0 to 5) |
.srec, .s19, .s28, .s37, .mot |
Motorola S-records (S1–S3 data, S7–S9 entry) |
| anything else | raw bytes, placed at --base ADDR |
Every checksum is checked. A HEX file must end with its end-of-file record, so a truncated download is refused. Two pieces that overlap are refused, and pieces that touch are merged.
How each byte gets there#
embflash asks the server for its memory map (qXfer:memory-map:read):
- Flash. Every block the image touches is erased, in runs of
blocks, with
vFlashErase; blocks the image does not touch keep their contents. The bytes are written withvFlashWriteand committed withvFlashDone. The block size is the server's. - RAM, and anything the server does not map. Written as memory with
X(binary). If the server does not takeX,embflashfalls back toM(hex). QEMU's gdbstub has no memory map and writes its flash this way.
Packets are as large as the server's PacketSize. A NAKed packet is sent
again. No-ack mode is used when the server offers it.
--verifyreads every byte back withmand names the first one that differs.--monitor CMDsendsCMDto the server first (qRcmd). For example,--monitor "reset halt"for OpenOCD. Repeat the flag for more commands, up to 16. The server's console output is copied to stderr.
Starting the program#
--run sets the registers and continues. The registers are found by
name in the server's target description (qXfer:features:read), so
embflash keeps no table of register numbers.
Cortex-M. If the description has
org.gnu.gdb.arm.m-profile, the core starts the way it does at reset:spis the vector table's first word;pcis the reset handler, with its Thumb bit cleared;- the Thumb bit is set in
xpsr.
The vector table is at the image's lowest address, or at
--vector-table ADDR.Other cores.
pcis the ELF entry, or--entry ADDR. HEX and S-records carry an entry in their start records.
Without --run, embflash detaches (D) and leaves the target halted.
Examples#
# QEMU: a board started with no program, its gdbstub on a socket
qemu-system-arm -M lm3s6965evb -nographic -S \
-chardev socket,path=g.sock,server=on,wait=off,id=g -gdb chardev:g &
embflash fw.elf --gdb unix:g.sock --verify --run
# OpenOCD with an ST-Link
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg &
embflash fw.hex --gdb localhost:3333 --monitor "reset halt" --verify
# a Black Magic Probe
embflash fw.elf --gdb serial:/dev/ttyACM0 --verify --run
# what would be written, with no target
embflash fw.bin --base 0x08000000 --dry-run
--dry-run prints the image's pieces and its entry. With --gdb, it
also prints the server's memory map, and writes nothing.
Exit status#
embflash exits with:
0when the image was written, and verified if--verifywas given.2when:- the image cannot be read;
- an option is malformed;
- the server refuses a request or does not answer within
--timeout(10 s by default); - a byte reads back wrong.
Each failure names its reason. A server that answers an erase or a write with an error is reported with that error.
Limits#
embflashhas been tested against QEMU and against a server that models a part's flash. It has not yet been tested against real probes.- Option bytes, mass erase and read-out protection are server-specific.
Reach them with
--monitor. - The transports need POSIX sockets and termios. Elsewhere
embflashbuilds, but it can only--dry-run.
Checked by#
tests/golden/embflash.sh runs against tests/golden/embflash/fakegdb.py.
That server models a part's flash and reports any rule a programmer breaks:
- an erase that is not whole, aligned blocks;
- a write to bytes that were not erased;
XorMinto flash;- a packet over
PacketSize; - a raw
$or*in binary data.
The checks:
- Every format: one firmware as ELF, HEX, S-records and raw binary
(all from
embpack) lands byte for byte. Exactly the blocks it touches are erased (check.py), and the memory map is read in both orders (flash first, as OpenOCD sends it, and RAM first, as pyOCD does). - Escapes: every byte value survives the binary escapes, in
vFlashWriteand inX, split over 256-byte packets. - Protocol: NAKed packets are sent again, and no-ack mode is taken.
Without a memory map the image is written as memory, with
Xor, when the server has noX, withM. - Run and verify:
--runsetssp,pcandxpsrfrom the vector table.--verifycatches a byte the server reads back wrong. - Refusals: a truncated HEX file, a bad checksum, overlapping
records, and a raw binary without
--baseare each refused for their own reason. - QEMU: a program put into QEMU's
lm3s6965evb, started with no image, runs and prints what it should.
Each of these checks has been seen to fail against a mutant of
embflash (18 of them).