Skip to content

Commit dae56d2

Browse files
committed
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.
1 parent 3f7c9d7 commit dae56d2

File tree

6 files changed

+105
-0
lines changed

6 files changed

+105
-0
lines changed

app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ zephyr_syscall_header(${APPLICATION_SOURCE_DIR}/include/drivers/ext_power.h)
2121
# Add your source file to the "app" target. This must come after
2222
# find_package(Zephyr) which defines the target.
2323
target_include_directories(app PRIVATE include)
24+
add_subdirectory(src/boot)
2425
target_sources(app PRIVATE src/stdlib.c)
2526
target_sources(app PRIVATE src/activity.c)
2627
target_sources(app PRIVATE src/behavior.c)

app/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ endmenu
513513

514514
menu "Advanced"
515515

516+
rsource "src/boot/Kconfig"
517+
516518
menu "Initialization Priorities"
517519

518520
if USB_DEVICE_STACK
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2024 The ZMK Contributors
2+
# SPDX-License-Identifier: MIT
3+
4+
description: |
5+
Driver for mapping bootloader boot mode to a magic value
6+
7+
compatible: "zmk,bootmode-to-magic-mapper"
8+
9+
include: base.yaml

app/src/boot/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
target_sources_ifdef(CONFIG_ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER app PRIVATE bootmode_to_magic_mapper.c)

app/src/boot/Kconfig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
config ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER
3+
bool "Magic Value Mapper"
4+
default y
5+
depends on DT_HAS_ZMK_BOOTMODE_TO_MAGIC_MAPPER_ENABLED
6+
7+
if ZMK_BOOTMODE_TO_MAGIC_VALUE_MAPPER
8+
9+
choice ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE
10+
prompt "Magic Value Bootloader Type"
11+
12+
config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_UNKNOWN
13+
bool "Unknown"
14+
15+
config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_TINYUF2
16+
bool "tinyuf2"
17+
18+
config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_BOSSA
19+
bool "Adafruit BOSSA"
20+
21+
22+
config ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_NRF52
23+
bool "Adafruit nRF52"
24+
25+
endchoice
26+
27+
config ZMK_BOOTMODE_BOOTLOADER_MAGIC_VALUE
28+
hex
29+
default 0xf01669ef if ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_TINYUF2 || ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_BOSSA
30+
default 0x57 if ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_NRF52
31+
32+
endif
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#define DT_DRV_COMPAT zmk_bootmode_to_magic_mapper
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/retention/bootmode.h>
11+
#include <zephyr/retention/retention.h>
12+
#include <zephyr/drivers/retained_mem.h>
13+
14+
static const struct device *magic_dev = DEVICE_DT_GET(DT_CHOSEN(zmk_magic_boot_mode));
15+
static const uint32_t bootloader_magic_value = CONFIG_ZMK_BOOTMODE_BOOTLOADER_MAGIC_VALUE;
16+
17+
static ssize_t btmm_ram_size(const struct device *dev) { return (ssize_t)1; }
18+
19+
static int btmm_ram_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size) {
20+
if (size != 1) {
21+
return -ENOTSUP;
22+
}
23+
24+
uint32_t val;
25+
int ret = retention_read(magic_dev, 0, (uint8_t *)&val, sizeof(val));
26+
if (ret < 0) {
27+
return ret;
28+
}
29+
30+
*buffer = (val == bootloader_magic_value) ? BOOT_MODE_TYPE_BOOTLOADER : BOOT_MODE_TYPE_NORMAL;
31+
32+
return 0;
33+
}
34+
35+
static int btmm_ram_write(const struct device *dev, off_t offset, const uint8_t *buffer,
36+
size_t size) {
37+
if (size != 1) {
38+
return -ENOTSUP;
39+
}
40+
41+
uint32_t val = (*buffer == BOOT_MODE_TYPE_BOOTLOADER) ? bootloader_magic_value : 0;
42+
43+
return retention_write(magic_dev, 0, (uint8_t *)&val, sizeof(val));
44+
}
45+
46+
static int btmm_ram_clear(const struct device *dev) {
47+
const struct btmm_config *config = dev->config;
48+
49+
return retention_clear(magic_dev);
50+
}
51+
52+
static const struct retained_mem_driver_api btmm_api = {
53+
.size = btmm_ram_size,
54+
.read = btmm_ram_read,
55+
.write = btmm_ram_write,
56+
.clear = btmm_ram_clear,
57+
};
58+
59+
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, 0, &btmm_api);

0 commit comments

Comments
 (0)