{"id":13647261,"url":"https://github.com/microsoft/uf2","last_synced_at":"2025-05-14T19:06:15.440Z","repository":{"id":20357207,"uuid":"75435631","full_name":"microsoft/uf2","owner":"microsoft","description":"UF2 file format specification","archived":false,"fork":false,"pushed_at":"2025-02-07T22:56:53.000Z","size":198,"stargazers_count":899,"open_issues_count":20,"forks_count":174,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-04-06T17:01:44.056Z","etag":null,"topics":["bootloader","makecode","uf2"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-02T22:24:50.000Z","updated_at":"2025-04-04T02:04:58.000Z","dependencies_parsed_at":"2023-02-10T02:46:40.150Z","dependency_job_id":"8c35aa33-523c-4a00-8f0b-fbe61a8eb6e2","html_url":"https://github.com/microsoft/uf2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fuf2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fuf2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fuf2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fuf2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/uf2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248766684,"owners_count":21158302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootloader","makecode","uf2"],"created_at":"2024-08-02T01:03:26.601Z","updated_at":"2025-04-13T19:19:24.162Z","avatar_url":"https://github.com/microsoft.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Guides and Learning","Others"],"sub_categories":["Firmware updates"],"readme":"# USB Flashing Format (UF2)\n\nUF2 is a file format, developed by Microsoft for [PXT](https://github.com/Microsoft/pxt) \n(also known as [Microsoft MakeCode](https://makecode.com)), that is particularly suitable for \nflashing microcontrollers over MSC (Mass Storage Class; aka removable flash drive).\n\nFor a more friendly explanation, check out [this blog post](https://makecode.com/blog/one-chip-to-flash-them-all).\nAlso, take a look at the list of [implementations](#implementations) at the bottom of this document.\n\n## Overview\n\nThe UF2 file consists of 512 byte blocks, each of which is self-contained and independent of others. \nEach 512 byte block consists of (see below for details):\n* magic numbers at the beginning and at the end\n* address where the data should be flashed\n* up to 476 bytes of data\n\nThe data transfers over MSC always arrive in multiples of 512 bytes.\nTogether with the FAT file system structure, this means that blocks of the\nUF2 file are always aligned with the MSC writes - the microcontroller \nnever gets a partial file.\n\nThe magic numbers let the microcontroller distinguish an UF2 file block from\nother data (eg., FAT table entry, or various book-keeping files stored by some\noperating systems).  When a UF2 block is recognized, it can be flashed\nimmediately (unless flash page size is more than 256 bytes; in that case a buffer\nis needed). The actual handling of file format during writing is very simple\n(~10 lines of C code in simplest version).\n\n## File format\n\nA UF2 file consists of 512 byte blocks. Each block starts with a 32 byte\nheader, followed by data, and a final magic number.\nAll fields, except for data, are 32 bit unsigned little endian integers.\n\n| Offset | Size | Value                                             |\n|--------|------|---------------------------------------------------|\n| 0      | 4    | First magic number, `0x0A324655` (`\"UF2\\n\"`)      |\n| 4      | 4    | Second magic number, `0x9E5D5157`                 |\n| 8      | 4    | Flags                                             |\n| 12     | 4    | Address in flash where the data should be written |\n| 16     | 4    | Number of bytes used in data (often 256)          |\n| 20     | 4    | Sequential block number; starts at 0              |\n| 24     | 4    | Total number of blocks in file                    |\n| 28     | 4    | File size or board family ID or zero              |\n| 32     | 476  | Data, padded with zeros                           |\n| 508    | 4    | Final magic number, `0x0AB16F30`                  |\n\nThe following C struct can be used:\n\n```C\nstruct UF2_Block {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t fileSize; // or familyID;\n    uint8_t data[476];\n    uint32_t magicEnd;\n} UF2_Block;\n```\n\n### Flags\n\nCurrently, there are five flags defined:\n\n* `0x00000001` - **not main flash** - this block should be skipped when writing the\n  device flash; it can be used to store \"comments\" in the file, typically\n  embedded source code or debug info that does not fit on the device flash\n* `0x00001000` - **file container** - see below\n* `0x00002000` - **familyID present** - when set, the `fileSize/familyID` holds a value\n  identifying the board family (usually corresponds to an MCU)\n* `0x00004000` - **MD5 checksum present** - see below\n* `0x00008000` - **extension tags present** - see below\n\n### Family ID\n\nThis field is optional, and should be set only when the corresponding\nflag is set. It is recommended that new bootloaders require the field to\nbe set appropriately, and refuse to flash UF2 files without it.\nIf you're developing your own bootloader, and your\nboard family isn't listed here, pick a new family ID at random. It's good\nto also send a PR here, so your family can be listed.\n\nIf the `familyID` doesn't match, the bootloader should disregard the\nentire block, including `blockNo` and `numBlocks` fields.\nIn particular, writing a full UF2 file with non-matching `familyID`\nshould not reset the board.\nThis also allows for several files with different `familyID` to be\nsimply concatenated together, and the whole resulting file to be copied\nto the device with only one actually being written to flash.\n\n#### Picking numbers at random\n\nThe reason to pick numbers at random is to minimize risk of collisions\nin the wild. Do not pick random numbers by banging on keyboard, or by using\n`0xdeadf00d`, `0x42424242` etc. A good way is to use the following\nshell command: `printf \"0x%04x%04x\\n\" $RANDOM $RANDOM`\nAnother good way is the link at the bottom of https://microsoft.github.io/uf2/patcher/\nThis procedure was unfortunately not used for the SAMD51 and NRF52840 below.\n\n#### Family list\n\nThe current master list of family IDs is maintained in a [JSON file](utils/uf2families.json).\n\n### Rationale\n\nThe magic number at the end is meant to mitigate partial block writes.\n\nSecond and final magic numbers were randomly selected, except for the last byte\nof final magic number, which was forced to be `'\\n'` (`0xA`). Together with the\nfirst magic number being `\"UF2\\n\"` this makes it easy to identify UF2 blocks in\na text editor.\n\nThe header is padded to 32 bytes, as hex editors commonly use 16 or 32 bytes\nas line length.  This way, the data payload is aligned to line start.\n\n32 bit integers are used for all fields so that large flash sizes can be\nsupported in future, as well as for simplicity. Little endian is used, as most\nmicrocontrollers are little endian. 8 bit microcontrollers can choose to just\nuse the first 16 bits of various header fields.\n\nThe total number of blocks in the file and the sequential block number make it\neasy for the bootloader to detect that all blocks have been transferred. It\nrequires one bit of memory per block (eg., on SAMD21G18A it's 128 bytes).\nAlternatively, the bootloader might ignore that and just implement a reset\nafter say 1 second break in incoming UF2 blocks.\n\n### Payload sizes\n\nThe number of data bytes is configurable and depends on the size of\nthe flash page (that is the smallest size that can be erased) on the\nmicrocontroller.\n\n* if the page size is more than `476` bytes, the bootloader should support\n  any payload size, as it needs to buffer the entire page in memory anyway\n* if the page size is less than `476` bytes, the payload should be a multiple\n  of page size, so it can be written without buffering; the target address\n  should also be a multiple of page size\n\nIn any event, payload size and target address should always be 4-byte aligned.\n\nNote that payload size of `256` is always correct, and makes it easy to convert\nbetween flash addresses and UF2 file offsets.\n\nFor example, on Atmel's SAMD21 chips the page size is `256` bytes, and this \nalso is the payload size. If the page size was `128` bytes, one could use\npayload of `128*3`. Nordic nRF51 has page size of `1024` bytes, and thus \nany payload size should be allowed.\n\n### Embedding sources\n\nSome IDEs will embed program sources in the UF2 file. This allows a UF2 files to be\nloaded by the IDE and serve as a natural backup and transfer format.\nThis can be done in two ways:\n\n* using the \"not main flash\" flag\n* using normal blocks that are flashed to the device\n\nIf the bootloader can expose `CURRENT.UF2` file (see below) and there is enough\nflash available, than the second option is more desirable, as it allows sharing\nprograms directly from the board.\n\nSee https://makecode.com/source-embedding for more info.\n\n### Robustness\n\nThe file format is designed specifically to deal with the following problems:\n\n* operating system (OS) writing blocks in different order than occurs in a file\n* OS writing blocks multiple times\n* OS writing data that is not UF2 blocks\n* OS writing first/final part of a block, possibly for metadata detection or search indexing\n\nThe only file system assumption we make is that blocks of file are aligned with\nblocks on the hard drive. It's likely true of many file systems besides FAT.\n\nWe also assume that USB MSC device reports its block size to be a multiple of `512`\nbytes. In the wild these devices always almost report exactly `512`, and some\noperating systems do not support other values.\n\n## Files exposed by bootloaders\n\nBootloaders may expose virtual files in their MSC devices.  These are\nstandardized here, so that flashing tools can automatically detect the\nbootloaders.\n\n* `INFO_UF2.TXT` - contains information about the bootloader build and the board on which it is running\n* `INDEX.HTM` - redirects to a page that contains an IDE or other information\n* `CURRENT.UF2` - the contents of the entire flash of the device, starting at `0x00000000`, with `256` payload size;\n  thus, the size of this file will report as twice the size of flash\n\nFlashing tools can use the presence of `INFO_UF2.TXT` (in upper or lower case,\nas FAT is case-insensitive) file as an indication that a given directory is\nactually a connected UF2 board. The other files should not be used for\ndetection.\n\nTypical `INFO_UF2.TXT` file looks like this:\n```\nUF2 Bootloader v1.1.3 SFA\nModel: Arduino Zero\nBoard-ID: SAMD21G18A-Zero-v0\n```\n\nThe `Board-ID` field is machine-readable and consists of a number of dash-separated tokens.\nThe first token is the CPU type, second is the board type, and third is the board revision.\nMore tokens can be also added.\n\nThe bootloader should contain its info file as a static string somewhere in its code.\nIf possible, the last word of the bootloader code should point to this string.\nThis way, the info file can be found in the initial section of the `CURRENT.UF2`\nfile as well. Thus, a board type can be determined from the contents of `CURRENT.UF2`.\nThis is particularly useful with the source embedding (see above).\n\n## File containers\n\nIt is also possible to use the UF2 format as a container for one or more\nregular files (akin to a TAR file, or ZIP archive without compression).  This\nis useful when the embedded device being flashed sports a file system.\n\nThe program to run may reside in one of the files, or in the main flash memory.\n\nIn such a usage the `file container` flag is set on blocks, the field `fileSize`\nholds the file size of the current file, and the field `targetAddr` holds the\noffset in current file.\n\nThe `not main flash` flag on blocks should be ignored when the `file container` is set.\n\nThe file name is stored at `\u0026data[payloadSize]` (ie., right after the actual payload) and\nterminated with a `0x00` byte.  The format of filename is dependent on the\nbootloader (usually implemented as some sort of file system daemon). \n\nThe bootloader will usually allow any size of the payload.\n\nThe current files on device might be exposed as multiple UF2 files, instead of\na single `CURRENT.UF2`. They may reside in directories, however, due to UF2 general\ndesign, it doesn't matter which directory the UF2 file is written to.\n\nTypical writing procedure is as follows:\n* validate UF2 magic numbers\n* make sure that `targetAddr \u003c fileSize` and that `fileSize` isn't out of reasonable range\n* write `0x00` at `data[475]` to ensure NUL termination of file name\n* read file name from `\u0026data[payloadSize]`; perform any mapping on the file name\n* create a directory where the file is to be written if it doesn't exist\n* open the file for writing\n* truncate the file to `fileSize`\n* seek `targetAddr`\n* write the payload (ie., `data[0 ... payloadSize - 1]`)\n* close the file\n\nThe fields `blockNo` and `numBlocks` refer to the entire UF2 file, not the current\nfile.\n\n## MD5 checksum\n\nWhen the `0x4000` flag is set, the last 24 bytes of `data[]` hold the following structure:\n\n| Offset | Size | Value                                             |\n|--------|------|---------------------------------------------------|\n| 0      | 4    | Start address of region                           |\n| 4      | 4    | Length of region in bytes                         |\n| 8      | 16   | MD5 checksum in binary format                     |\n\nThe flashing program should compute the MD5 sum of the specified region.\nIf the region checksum matches, flashing of the current block can be skipped.\nTypically, many blocks in sequence will have the same region specified,\nand can all be skipped, if the matching succeeded.\nThe position of the current block will typically be inside of the region.\nThe position and size of the region should be multiple of page erase size\n(4k or 64k on typical SPI flash).\n\nThis is currently only used on ESP32, which is also why MD5 checksum is used.\n\n## Extension tags\n\nWhen the `0x8000` flag is set, additional information can be appended right after\npayload data (i.e., it starts at `32 + payloadSize`).\nEvery tag starts at 4 byte boundary.\nThe first byte of tag contains its total size in bytes (including the size byte\nand type designation).\nThe next three bytes designate the type of tag (if you want to define custom\ntags, pick them at random).\nThe last tag has size of `0` and type of `0`.\n\nStandard tag designations follow:\n* `0x9fc7bc` - version of firmware file - UTF8 semver string\n* `0x650d9d` - description of device for which the firmware file is destined (UTF8)\n* `0x0be9f7` - page size of target device (32 bit unsigned number)\n* `0xb46db0` - SHA-2 checksum of firmware (can be of various size)\n* `0xc8a729` - device type identifier - a refinement of `familyID` meant to identify a kind of device\n  (eg., a toaster with specific pinout and heating unit), not only MCU; 32 or 64 bit number; can be hash of `0x650d9d`\n\nFor example, the following bytes encode firmware version `0.1.2` for device\nnamed `ACME Toaster mk3` (line breaks added for clarity):\n\n```\n09 bc c7 9f 30 2e 31 2e 32 00 00 00\n14 9d 0d 65 41 43 4d 45 20 54 6f 61 73 74 65 72 20 6d 6b 33\n00 00 00 00\n```\n\nExtension tags can, but don't have to, be repeated in all blocks.\n\n## Implementations\n\n### Bootloaders\n\n* [Microchip ATSAMD21 and ATSAMD51](https://github.com/Microsoft/uf2-samdx1)\n* [Arduino UNO](https://github.com/mmoskal/uf2-uno)\n* [STM32F103](https://github.com/mmoskal/uf2-stm32)\n* [STM32F4](https://github.com/mmoskal/uf2-stm32f)\n* [Nordic NRF52840](https://github.com/adafruit/Adafruit_nRF52840_Bootloader)\n* [Linux (RPi Zero)](https://github.com/microsoft/uf2-linux)\n* [Cypress FX2](https://github.com/whitequark/libfx2/tree/master/firmware/boot-uf2)\n* [Tiny UF2](https://github.com/adafruit/tinyuf2) - Support ESP32-S2, iMXRT10xx, STM32F4\n* [RP2040 chip](https://www.raspberrypi.org/products/raspberry-pi-pico/) - native support in silicon\n* [UF2-ChibiOS](https://github.com/striso/uf2-ChibiOS) - Supports STM32H7\n\nThere's an ongoing effort to implement UF2 in [Codal](https://github.com/lancaster-university/codal-core).\n\n### Editors\n\n* https://arcade.makecode.com\n* https://makecode.adafruit.com\n* https://makecode.seeedstudio.com\n* https://maker.makecode.com\n\n### Libraries\n\n* https://www.npmjs.com/package/uf2\n\n## License\n\nMIT\n\n## Code of Conduct\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fuf2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2Fuf2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fuf2/lists"}