TinyUF2 Bootloader
The TinyUF2 Bootloader is a magic value type bootloader, with some extra setup used to integrate with it.
Kconfig Symbol Enablement
Three Kconfig symbols need to be enabled for this feature to work, namely RETAINED_MEM, RETENTION, and RETENTION_BOOT_MODE. Typically, this is done by implying the symbols for the board symbol in the Kconfig.<board>, file, e.g.:
config BOARD_TOFU65
select SOC_RP2040
imply RETAINED_MEM
imply RETENTION
imply RETENTION_BOOT_MODE
By using imply at the board level, users of the board can choose to override the setting and disable the feature if they so choose.
Adjust The Existing RAM node
For TinyUF2, we'll first adjust the SRAM to ensure Zephyr does not overwrite the memory location the bootloader inspect to determine if it should enter bootloader mode:
&sram0 {
reg = <0x20000000 0x1FFFC>;
};
Note:
- The
0x20000000address is the address of the RAM for the target. This is nearly always0x20000000 - The exact value of
0x1FFFCwill depend on the total RAM on the target. The value should be the total RAM, minus 4-bytes, in hex
Add a New Memory Region Node with Retainer RAM
/ {
sram@2001FFFC {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x2001FFFC 0x4>;
zephyr,memory-region = "RetainedMem";
status = "okay";
retainedmem {
compatible = "zephyr,retained-ram";
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
magic_retention: retention@0 {
compatible = "zephyr,retention";
status = "okay";
reg = <0x0 0x4>;
};
};
};
};
Note:
- The node
sram@2001FFFCand the correspondingregproperty values are obtained by adding the base RAM address (.e.g.0x20000000) to the shrunk RAM size (e.g.0x1FFFC) to get the new start address for the area of reserved RAM. - The magic values in TinyUF2 are 32-bits (4 bytes), so the second
regsize value is0x4.
Magic Mapper node
Next, we'll set up our mapping retained mem driver, which will map from the Zephyr boot mode values to the values the bootloader is looking for:
/ {
magic_mapper {
compatible = "zmk,bootmode-to-magic-mapper";
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
boot_retention: retention@0 {
compatible = "zephyr,retention";
status = "okay";
reg = <0x0 0x1>;
};
};
};
Assign Chosen Properties
Finally, we'll assign two chosen properties for the two nodes that have been defined:
/ {
chosen {
zephyr,boot-mode = &boot_retention;
zmk,magic-boot-mode = &magic_retention;
};
};
Magic Value Type Kconfig
Lastly, one Kconfig choice needs to be set, e.g. in Kconfig.defaults for the board:
choice ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE
default ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_TINYUF2
endchoice