Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions loader/main.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* Copyright (C) 2024 Arduino SA
*
Expand All @@ -15,21 +15,28 @@
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_uart.h>

#include <zephyr/sys/byteorder.h>

#include <stdlib.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/uart/cdc_acm.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/usb/usb_device.h>

#define HEADER_LEN 16
typedef union {
struct {
uint8_t _padding[7];
uint8_t ver; // @ 0x07
uint32_t len; // @ 0x08
uint16_t magic; // @ 0x0c
uint8_t flags; // @ 0x0e
// uint8_t _padding; last unused byte in header
} __attribute__((packed));
uint8_t bytes[16];
} sketch_header_v1;

struct sketch_header_v1 {
uint8_t ver; // @ 0x07
uint32_t len; // @ 0x08
uint16_t magic; // @ 0x0c
uint8_t flags; // @ 0x0e
} __attribute__((packed));
#define HEADER_LEN sizeof(sketch_header_v1)

#define SKETCH_FLAG_DEBUG 0x01
#define SKETCH_FLAG_LINKED 0x02
Expand Down Expand Up @@ -104,16 +111,20 @@
uintptr_t base_addr =
DT_REG_ADDR(DT_GPARENT(DT_NODELABEL(user_sketch))) + DT_REG_ADDR(DT_NODELABEL(user_sketch));

char header[HEADER_LEN];
rc = flash_area_read(fa, 0, header, sizeof(header));
sketch_header_v1 sketch_hdr;
rc = flash_area_read(fa, 0, sketch_hdr.bytes, sizeof(sketch_hdr.bytes));
if (rc) {
printk("Failed to read header, rc %d\n", rc);
return rc;
}

bool sketch_valid = true;
struct sketch_header_v1 *sketch_hdr = (struct sketch_header_v1 *)(header + 7);
if (sketch_hdr->ver != 0x1 || sketch_hdr->magic != 0x2341) {

// Ensure endianness is preserved in fields of header with more than 1 byte
sketch_hdr.len = sys_le32_to_cpu(sketch_hdr.len);
sketch_hdr.magic = sys_le16_to_cpu(sketch_hdr.magic);

if (sketch_hdr.ver != 0x1 || sketch_hdr.magic != 0x2341) {
Copy link
Member

@leonardocavagnis leonardocavagnis Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (sketch_hdr.ver != 0x1 || sketch_hdr.magic != 0x2341) {
if (sketch_hdr.ver != SKETCH_VER || sketch_hdr.magic != SKETCH_MAGIC) {

Consider replacing the magic numbers with #define constants for maintainability

printk("Invalid sketch header\n");
sketch_valid = false;
// This is not a valid sketch, but try to start a shell anyway
Expand Down Expand Up @@ -152,7 +163,7 @@
_bootanimation_end = _bootanimation + user_bootanimation->len_loop;
}

if ((!sketch_valid) || !(sketch_hdr->flags & SKETCH_FLAG_IMMEDIATE)) {
if ((!sketch_valid) || !(sketch_hdr.flags & SKETCH_FLAG_IMMEDIATE)) {
// Start the bootanimation while waiting for the MPU to boot
const struct gpio_dt_spec spec =
GPIO_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), control_gpios, 0);
Expand Down Expand Up @@ -185,8 +196,8 @@
while (!sketch_valid) {
__asm__("bkpt");
// poll the first bytes, if filled try to use them for booting
sketch_hdr = (struct sketch_header_v1 *)(ram_firmware + 7);
if (sketch_hdr->ver == 0x1 && sketch_hdr->magic == 0x2341) {
memcpy(sketch_hdr.bytes, ram_firmware, sizeof(sketch_hdr));
if (sketch_hdr.ver == 0x1 && sketch_hdr.magic == 0x2341) {
// Found valid data, use it for booting
base_addr = (uintptr_t)ram_firmware;
*ram_start = 0;
Expand All @@ -196,10 +207,10 @@
}
#endif

size_t sketch_buf_len = sketch_hdr->len;
size_t sketch_buf_len = sketch_hdr.len;

#if TARGET_HAS_USB_CDC_SHELL
int debug = (!sketch_valid) || (sketch_hdr->flags & SKETCH_FLAG_DEBUG);
int debug = (!sketch_valid) || (sketch_hdr.flags & SKETCH_FLAG_DEBUG);
if (debug && strcmp(k_thread_name_get(k_current_get()), "main") == 0) {
// disables default shell on UART
shell_uninit(shell_backend_uart_get_ptr(), NULL);
Expand All @@ -216,7 +227,7 @@
}
#endif

if (sketch_hdr->flags & SKETCH_FLAG_LINKED) {
if (sketch_hdr.flags & SKETCH_FLAG_LINKED) {
#ifdef CONFIG_BOARD_ARDUINO_PORTENTA_C33
#if CONFIG_MPU
barrier_dmem_fence_full();
Expand Down
Loading