The UF2 specification is the README of Microsoft’s uf2 repository on
GitHub, which this page follows. A UF2 file is nothing but 512-byte blocks, each
complete in itself, so a bootloader that appears as a USB drive can write each block to
flash as the operating system copies it, whatever order the blocks arrive in.
Block layout
Every field except the data is a 32-bit unsigned little-endian integer.
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 4 | magicStart0 | 0x0A324655: the text UF2 and a line feed. |
4 | 4 | magicStart1 | 0x9E5D5157. |
8 | 4 | flags | See flags. |
12 | 4 | targetAddr | Flash address the data is written to (or, in a file container, the offset in the file). |
16 | 4 | payloadSize | Number of data bytes used, often 256. |
20 | 4 | blockNo | Sequential block number, from 0. |
24 | 4 | numBlocks | Total number of blocks in the file. |
28 | 4 | fileSize / familyID | The file size (file container), the board family ID (flag 0x2000), or zero. |
32 | 476 | data | The payload, padded with zeros; extensions may follow the payload inside this area. |
508 | 4 | magicEnd | 0x0AB16F30. |
The final magic number lets a bootloader spot a block the operating system wrote only partly.
Flags
| Value | Name | Meaning |
|---|---|---|
0x00000001 | not main flash | Do not write this block to the device’s flash; used for comments in the file, such as source code or debugging information. |
0x00001000 | file container | The block is part of a file container; see file container. |
0x00002000 | familyID present | The word at offset 28 is a board family ID; see family IDs. |
0x00004000 | MD5 checksum present | The data area ends with an MD5 region descriptor; see MD5. |
0x00008000 | extension tags present | Extension tags follow the payload; see extension tags. |
No other flags are defined.
Family ID rules
- The family ID is optional, but new bootloaders should require it and refuse files without it.
- A bootloader must ignore a block whose family ID does not match its own completely, including that block’s
blockNoandnumBlocks; a file for another family must not make the board reset. - So files for different families can be joined into one, and each board flashes only its own blocks.
- A new family ID should be picked at random (the README suggests
printf "0x%04x%04x\n" $RANDOM $RANDOM), not a pattern such as0xdeadf00d, and added to the list in the repository.
File container (flag 0x1000)
A UF2 file can carry ordinary files instead of flash contents. In such blocks:
| Field | Meaning |
|---|---|
fileSize (offset 28) | Size of the file this block belongs to. |
targetAddr | Offset of this block’s data within that file. |
data[payloadSize] onwards | The file name, ending in a 0x00 byte. |
blockNo, numBlocks | Still count blocks of the whole UF2 file, not of the one contained file. |
The not-main-flash flag is ignored in container blocks. A reader writes a block like
this: check the magic numbers; check that targetAddr is less than
fileSize and that fileSize is reasonable; write
0x00 at data[475] so the name is always terminated; read the
name (mapping it if needed); create its directory; open the file; truncate it to
fileSize; seek to targetAddr; write
data[0 … payloadSize − 1]; close the file.
MD5 checksum (flag 0x4000)
The last 24 bytes of the data area describe a region of flash:
| Offset in the 24 bytes | Size | Meaning |
|---|---|---|
0 | 4 | Start address of the region. |
4 | 4 | Length of the region in bytes. |
8 | 16 | MD5 checksum of the region, in binary. |
The flasher computes the MD5 of that region of the device’s flash; if it matches, the block need not be written. Regions should start and end on erase-page boundaries (4 KiB or 64 KiB on typical SPI flash). The README notes that only ESP32 uses this so far.
Payload size and alignment
payloadSizeandtargetAddrmust always be multiples of 4.- If the flash erase page is larger than 476 bytes, any payload size works, because the bootloader has to buffer a whole page anyway.
- If the page is smaller than 476 bytes, the payload size and the target address must both be multiples of the page size.
- A payload of 256 bytes always works and makes it easy to convert between flash addresses and file offsets.
How a bootloader treats blocks
- It recognises blocks by the magic numbers and ignores everything else the operating system writes (FAT entries, bookkeeping files).
- Blocks may arrive out of order, twice, or as partial writes; the format is meant to cope with all of these.
- It assumes blocks line up with file-system blocks; the USB mass-storage block size must be a multiple of 512.
- It can write a block at once, unless the flash page is larger than 256 bytes, in which case it buffers.
- It skips not-main-flash blocks and blocks for another family.
- To know it has everything it needs one bit of memory per block (from
blockNoandnumBlocks); simpler bootloaders instead reset after about a second with no new blocks.
Files a UF2 drive shows
| File | Meaning |
|---|---|
INFO_UF2.TXT | Text about the bootloader build and the board, including a Board-ID line of dash-separated tokens: CPU type, board type, board revision and optional extras. Its presence (in any case) is how tools recognise a UF2 drive; it is the only file that should be used for that. |
INDEX.HTM | Redirects to an IDE or another page about the board. |
CURRENT.UF2 | The whole flash from address 0 as UF2 blocks with 256-byte payloads, so it shows as twice the flash size. The bootloader’s information string should sit near the start of flash so the board type can be read from it. |
Worked example
Offset Bytes Field
0 55 46 32 0A magicStart0 0x0A324655 ("UF2\n")
4 57 51 5D 9E magicStart1 0x9E5D5157
8 00 20 00 00 flags 0x00002000, family ID present
12 00 00 00 10 targetAddr 0x10000000
16 00 01 00 00 payloadSize 256
20 00 00 00 00 blockNo 0
24 01 00 00 00 numBlocks 1
28 56 FF 8B E4 familyID 0xE48BFF56 (Raspberry Pi RP2040)
32 … 256 bytes of data, then 220 zero bytes
508 30 6F B1 0A magicEnd 0x0AB16F30
Sources
- USB Flashing Format (UF2) – Microsoft’s
uf2repository README: the block, flags, family rules, file container, MD5 and extension tags, payload rules, bootloader behaviour and the virtual files - uf2families.json – the family ID used in the example
The README gives no version number or date for the specification.