feat(core): mapper for magic bootloader values.

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.
This commit is contained in:
Peter Johanson 2024-12-02 00:24:45 -07:00
parent 4699235830
commit c94f52147d
6 changed files with 108 additions and 0 deletions

View File

@ -23,6 +23,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)

View File

@ -474,6 +474,8 @@ endmenu
menu "Advanced"
rsource "src/boot/Kconfig"
menu "Initialization Priorities"
if USB_DEVICE_STACK

View File

@ -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

View File

@ -0,0 +1,2 @@
target_sources_ifdef(CONFIG_ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER app PRIVATE bootmode_to_magic_mapper.c)

31
app/src/boot/Kconfig Normal file
View File

@ -0,0 +1,31 @@
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

View File

@ -0,0 +1,63 @@
/*
* 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));
#define MAGIC_DEST_ONE_BYTE (DT_REG_SIZE(DT_CHOSEN(zmk_magic_boot_mode)) == 1)
#if MAGIC_DEST_ONE_BYTE
typedef uint8_t magic_val_t;
#else
typedef uint32_t magic_val_t;
#endif
static const magic_val_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;
}
magic_val_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;
}
magic_val_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);