Add second pre-loaded app slot in flash

This commit is contained in:
Mikael Ågren 2025-03-18 13:18:33 +01:00
parent 6ad32f7317
commit 970668a47b
No known key found for this signature in database
GPG Key ID: E02DA3D397792C46
6 changed files with 73 additions and 35 deletions

View File

@ -107,6 +107,26 @@ int main(void)
syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0);
} break;
case '6': {
uint8_t string[] = "0123456789abcdef0123456789abcdef012"
"3456789abcdef0123456789abcdef";
rst.type = START_FLASH2_VER;
hex_string_to_bytes(string, (uint8_t *)&rst.app_digest,
sizeof(rst.app_digest));
syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0);
} break;
case '7': {
uint8_t tkeylibs_example_app_digest[] =
"a97f6ec2112067c4b5b5860521e252a095d221652f7b3d056b"
"d98eaba40b4967";
rst.type = START_FLASH2_VER;
hex_string_to_bytes(tkeylibs_example_app_digest,
(uint8_t *)&rst.app_digest,
sizeof(rst.app_digest));
syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0);
} break;
default:
break;
}

View File

@ -71,7 +71,8 @@ static uint32_t xorwow(uint32_t state, uint32_t acc);
#endif
static void scramble_ram(void);
static int compute_app_digest(uint8_t *digest);
static int load_flash_app(struct partition_table *part_table, uint8_t digest[32]);
static int load_flash_app(struct partition_table *part_table,
uint8_t digest[32], uint8_t slot);
static enum state start_where(struct context *ctx);
static void print_hw_version(void)
@ -375,9 +376,10 @@ static void jump_to_app(void)
__builtin_unreachable();
}
static int load_flash_app(struct partition_table *part_table, uint8_t digest[32])
static int load_flash_app(struct partition_table *part_table,
uint8_t digest[32], uint8_t slot)
{
if (preload_load(part_table) == -1) {
if (preload_load(part_table, slot) == -1) {
return -1;
}
@ -461,25 +463,25 @@ static enum state start_where(struct context *ctx)
case START_DEFAULT:
// fallthrough
case START_FLASH1:
ctx->flash_slot = 1;
ctx->flash_slot = 0;
ctx->ver_digest = NULL;
return FW_STATE_LOAD_FLASH;
case START_FLASH2:
ctx->flash_slot = 2;
ctx->flash_slot = 1;
ctx->ver_digest = NULL;
return FW_STATE_LOAD_FLASH;
case START_FLASH1_VER:
ctx->flash_slot = 1;
ctx->flash_slot = 0;
ctx->ver_digest = resetinfo->app_digest;
return FW_STATE_LOAD_FLASH;
case START_FLASH2_VER:
ctx->flash_slot = 2;
ctx->flash_slot = 1;
ctx->ver_digest = resetinfo->app_digest;
return FW_STATE_LOAD_FLASH;
@ -599,7 +601,7 @@ int main(void)
// authenticated.
part_table.pre_app_data.status = PRE_LOADED_STATUS_PRESENT;
if (load_flash_app(&part_table, ctx.digest) < 0) {
if (load_flash_app(&part_table, ctx.digest, ctx.flash_slot) < 0) {
debug_puts("Couldn't load app from flash\n");
state = FW_STATE_FAIL;
break;

View File

@ -13,12 +13,13 @@
/* ---- ---- ---- */
/* Partition 64KiB 0x20000 */
/* ---- ---- ---- */
/* Pre load 128KiB 0x30000 */
/* Pre load 1 128KiB 0x30000 */
/* Pre load 2 128KiB 0x50000 */
/* ---- ---- ---- */
/* storage 1 128KiB 0x50000 */
/* storage 2 128KiB 0x70000 */
/* storage 3 128KiB 0x90000 */
/* storage 4 128KiB 0xB0000 */
/* storage 1 128KiB 0x70000 */
/* storage 2 128KiB 0x90000 */
/* storage 3 128KiB 0xB0000 */
/* storage 4 128KiB 0xD0000 */
/* ---- ---- ---- */
/* To simplify all blocks are aligned with the 64KiB blocks on the W25Q80DL
@ -42,7 +43,7 @@
// Pre-loaded app present but not yet authenticated
#define PRE_LOADED_STATUS_PRESENT 0x02
#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + SIZE_PRE_LOADED_APP)
#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + (2 * SIZE_PRE_LOADED_APP))
#define SIZE_STORAGE_AREA 0x20000UL // 128KiB
#define N_STORAGE_AREA 4

View File

@ -14,7 +14,8 @@
#include "preload_app.h"
/* Returns non-zero if the app is valid */
bool preload_check_valid_app(struct partition_table *part_table)
bool preload_check_valid_app(struct partition_table *part_table,
uint8_t slot)
{
if (part_table->pre_app_data.status == 0x00 &&
@ -27,17 +28,18 @@ bool preload_check_valid_app(struct partition_table *part_table)
}
/* Loads a preloaded app from flash to app RAM */
int preload_load(struct partition_table *part_table)
int preload_load(struct partition_table *part_table, uint8_t from_slot)
{
/*Check for a valid app in flash */
if (!preload_check_valid_app(part_table)) {
if (!preload_check_valid_app(part_table, from_slot)) {
return -1;
}
uint8_t *loadaddr = (uint8_t *)TK1_RAM_BASE;
/* Read from flash, straight into RAM */
int ret = flash_read_data(ADDR_PRE_LOADED_APP, loadaddr,
part_table->pre_app_data.size);
int ret = flash_read_data(ADDR_PRE_LOADED_APP +
from_slot * SIZE_PRE_LOADED_APP,
loadaddr, part_table->pre_app_data.size);
return ret;
}
@ -47,7 +49,7 @@ int preload_load(struct partition_table *part_table)
* Once done, call preload_store_finalize() with the last parameters.
* */
int preload_store(struct partition_table *part_table, uint32_t offset,
uint8_t *data, size_t size)
uint8_t *data, size_t size, uint8_t to_slot)
{
/* Check if we are allowed to store */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
@ -55,7 +57,7 @@ int preload_store(struct partition_table *part_table, uint32_t offset,
}
/* Check for a valid app in flash, bale out if it already exists */
if (preload_check_valid_app(part_table)) {
if (preload_check_valid_app(part_table, to_slot)) {
return -1;
}
@ -74,7 +76,7 @@ int preload_store(struct partition_table *part_table, uint32_t offset,
}
int preload_store_finalize(struct partition_table *part_table, bool use_uss,
uint8_t *uss, size_t app_size)
uint8_t *uss, size_t app_size, uint8_t to_slot)
{
/* Check if we are allowed to store */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
@ -82,7 +84,7 @@ int preload_store_finalize(struct partition_table *part_table, bool use_uss,
}
/* Check for a valid app in flash, bale out if it already exists */
if (preload_check_valid_app(part_table)) {
if (preload_check_valid_app(part_table, to_slot)) {
return -1;
}
@ -107,7 +109,7 @@ int preload_store_finalize(struct partition_table *part_table, bool use_uss,
return 0;
}
int preload_delete(struct partition_table *part_table)
int preload_delete(struct partition_table *part_table, uint8_t slot)
{
/* Check if we are allowed to deleted */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
@ -115,7 +117,7 @@ int preload_delete(struct partition_table *part_table)
}
/*Check for a valid app in flash */
if (!preload_check_valid_app(part_table)) {
if (!preload_check_valid_app(part_table, slot)) {
return 0;
// TODO: Nothing here, return zero like all is good?
}

View File

@ -9,12 +9,13 @@
#include <stddef.h>
#include <stdint.h>
bool preload_check_valid_app(struct partition_table *part_table);
int preload_load(struct partition_table *part_table);
bool preload_check_valid_app(struct partition_table *part_table,
uint8_t slot);
int preload_load(struct partition_table *part_table, uint8_t from_slot);
int preload_store(struct partition_table *part_table, uint32_t offset,
uint8_t *data, size_t size);
uint8_t *data, size_t size, uint8_t to_slot);
int preload_store_finalize(struct partition_table *part_table, bool use_uss,
uint8_t *uss, size_t app_size);
int preload_delete(struct partition_table *part_table);
uint8_t *uss, size_t app_size, uint8_t to_slot);
int preload_delete(struct partition_table *part_table, uint8_t slot);
#endif

View File

@ -1,12 +1,24 @@
#!/bin/bash -e
if [ $# != 1 ]
if [ $# != 2 ]
then
echo "Usage: $0 app_file"
echo "Usage: $0 slot_num app_file"
echo ""
echo "Where slot_num is 0 or 1."
exit
fi
APP="$1"
SLOT_NUM="$1"
APP="$2"
if [ "$SLOT_NUM" = "0" ]; then
START_ADDRESS=0x30000
elif [ "$SLOT_NUM" = "1" ]; then
START_ADDRESS=0x50000
else
echo "Invalid slot_num"
exit 1
fi
echo "WARNING: Will erase entire partition table."
read -p "Press CTRL-C to abort. Press key to continue." -n1 -s
@ -15,7 +27,7 @@ read -p "Press CTRL-C to abort. Press key to continue." -n1 -s
tillitis-iceprog -o 0x20000 -e 64k
# Erase existing pre loaded app
tillitis-iceprog -o 0x30000 -e 128k
tillitis-iceprog -o "$START_ADDRESS" -e 128k
# Write pre loaded app
tillitis-iceprog -o 0x30000 "$APP"
tillitis-iceprog -o "$START_ADDRESS" "$APP"