Skip to content

Commit

Permalink
feat(core): mapper for magic bootloader values.
Browse files Browse the repository at this point in the history
To trigger bootloaders that use a magic value in RAM to trigger
bootloader mode, add a mapping retained memory driver that maps
write/read of boot mode values to a special magic value stored
in the actually backing RAM.
  • Loading branch information
petejohanson committed Dec 3, 2024
1 parent 3f7c9d7 commit 24c3fd0
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ zephyr_syscall_header(${APPLICATION_SOURCE_DIR}/include/drivers/ext_power.h)
# Add your source file to the "app" target. This must come after
# find_package(Zephyr) which defines the target.
target_include_directories(app PRIVATE include)
add_subdirectory(src/boot)
target_sources(app PRIVATE src/stdlib.c)
target_sources(app PRIVATE src/activity.c)
target_sources(app PRIVATE src/behavior.c)
Expand Down
2 changes: 2 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ endmenu

menu "Advanced"

rsource "src/boot/Kconfig"

menu "Initialization Priorities"

if USB_DEVICE_STACK
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024 The ZMK Contributors
# SPDX-License-Identifier: MIT

description: |
Driver for mapping bootloader boot mode to a magic value
compatible: "zmk,bootmode-to-magic-mapper"

include: base.yaml
2 changes: 2 additions & 0 deletions app/src/boot/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

target_sources_ifdef(CONFIG_ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER app PRIVATE bootmode_to_magic_mapper.c)
32 changes: 32 additions & 0 deletions app/src/boot/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

config ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER
bool "Magic Value Mapper"
default y
depends on DT_HAS_ZMK_BOOTMODE_TO_MAGIC_MAPPER_ENABLED

if ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER

choice ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE
prompt "Magic Value Bootloader Type"

config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_UNKNOWN
bool "Unknown"

config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_TINYUF2
bool "tinyuf2"

config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_BOSSA
bool "Adafruit BOSSA"


config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_NRF52
bool "Adafruit nRF52"

endchoice

config ZMK_BOOTMODE_BOOTLOADER_MAGIC_VALUE
hex
default 0xf01669ef if ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_TINYUF2 || ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_BOSSA || BOOTLOADER_BOSSA_ADAFRUIT_UF2
default 0x57 if ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_NRF52

endif
55 changes: 55 additions & 0 deletions app/src/boot/bootmode_to_magic_mapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define DT_DRV_COMPAT zmk_bootmode_to_magic_mapper

#include <zephyr/device.h>
#include <zephyr/retention/bootmode.h>
#include <zephyr/retention/retention.h>
#include <zephyr/drivers/retained_mem.h>

static const struct device *magic_dev = DEVICE_DT_GET(DT_CHOSEN(zmk_magic_boot_mode));
static const uint32_t bootloader_magic_value = CONFIG_ZMK_BOOTMODE_BOOTLOADER_MAGIC_VALUE;

static ssize_t btmm_ram_size(const struct device *dev) { return (ssize_t)1; }

static int btmm_ram_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size) {
if (size != 1) {
return -ENOTSUP;
}

uint32_t val;
int ret = retention_read(magic_dev, 0, (uint8_t *)&val, sizeof(val));
if (ret < 0) {
return ret;
}

*buffer = (val == bootloader_magic_value) ? BOOT_MODE_TYPE_BOOTLOADER : BOOT_MODE_TYPE_NORMAL;

return 0;
}

static int btmm_ram_write(const struct device *dev, off_t offset, const uint8_t *buffer,
size_t size) {
if (size != 1) {
return -ENOTSUP;
}

uint32_t val = (*buffer == BOOT_MODE_TYPE_BOOTLOADER) ? bootloader_magic_value : 0;

return retention_write(magic_dev, 0, (uint8_t *)&val, sizeof(val));
}

static int btmm_ram_clear(const struct device *dev) { return retention_clear(magic_dev); }

static const struct retained_mem_driver_api btmm_api = {
.size = btmm_ram_size,
.read = btmm_ram_read,
.write = btmm_ram_write,
.clear = btmm_ram_clear,
};

DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, 0, &btmm_api);

0 comments on commit 24c3fd0

Please sign in to comment.