---
title: SAMD21 UF2 Bootloader
sidebar_label: SAMD21
---

import BaseConfig from "./_base-config.md";

The [SAMD21 UF2 Bootloader](https://github.com/adafruit/uf2-samdx1) is a [magic value type bootloader](./index.mdx#magic-value-bootloaders), with some extra setup used to integrate with it.

<BaseConfig />

## Adjust The Existing RAM node

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:

```dts
&sram0 {
    reg = <0x20000000 0x7FFC>;
};
```

Note:

- The `0x20000000` address is the address of the RAM for the target. This is nearly always `0x20000000`.
- The exact value of `0x7FFC` will 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

```dts
/ {
    sram@20007FFC {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x20007FFC 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@20007FFC` and the corresponding `reg` property values are obtained by adding the base RAM address (.e.g. `0x20000000`) to the shrunk RAM size (e.g. `0x7FFC`) to get the new start address for the area of reserved RAM.
- The magic values are 32-bits (4 bytes), so the second `reg` size value is `0x4`.

## 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:

```dts
/ {
    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:

```dts
/ {
    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_ADAFRUIT_BOSSA

endchoice
```
