Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootloaders/riotboot_vfs: add VFS based bootloader #17379

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
bootloaders/riotboot_vfs: add VFS based bootloader
  • Loading branch information
benpicco committed May 26, 2022
commit 8dec3799007141480507842ed23fa4e41dd12294
4 changes: 3 additions & 1 deletion bootloaders/riotboot_common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ CFLAGS += -DRIOTBOOT
# Disable unused modules
CFLAGS += -DNDEBUG -DLOG_LEVEL=LOG_NONE
DISABLE_MODULE += core_init core_msg core_panic
DISABLE_MODULE += auto_init auto_init_%
ifeq (,$(filter auto_init,$(USEMODULE)))
DISABLE_MODULE += auto_init auto_init_%
endif
DISABLE_MODULE += pm_layered

# avoid using stdio
Expand Down
12 changes: 12 additions & 0 deletions bootloaders/riotboot_vfs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Default RIOT bootloader
APPLICATION = riotboot_vfs

USEMODULE += auto_init
USEMODULE += riotboot_vfs
USEMODULE += vfs_default

# In riotboot we do everything on the ISR stack
DISABLE_MODULE += core_thread
CFLAGS += -DISR_STACKSIZE=2048

include ../riotboot_common.mk
110 changes: 110 additions & 0 deletions bootloaders/riotboot_vfs/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2021 ML!PA Consulting GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup bootloaders
* @{
*
* @file
* @brief Bootloader to load firmware from external storage via VFS
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*
* @}
*/

#include <fcntl.h>
#include "cpu.h"
#include "panic.h"
#include "riotboot/slot.h"
#include "riotboot/vfs.h"
#include "vfs.h"
#include "vfs_util.h"
#include "periph/flashpage.h"

#define ENABLE_DEBUG 0
#include "debug.h"

#ifndef FLASHPAGE_SIZE
#define FLASHPAGE_SIZE 1024
#endif

static void _flash_image(const char *file)
{
static uint8_t buffer[FLASHPAGE_SIZE];
uint8_t *dst = (void *)(uintptr_t)SLOT0_OFFSET;
int res, fd = vfs_open(file, O_RDONLY, 0);

DEBUG("flashing %s…\n", file);

if (fd < 0) {
DEBUG("can't open: %d\n", fd);
return;
}

/* get image size */
off_t size = vfs_lseek(fd, 0, SEEK_END);
unsigned last_page = flashpage_page((void *)(uintptr_t)(SLOT0_OFFSET + size));

/* backup old image, close new image to conserve fds */
vfs_close(fd);
if (riotboot_vfs_dump_rom(RIOTBOOT_VFS_BACKUP_FILE) <= 0) {
DEBUG("can't backup current ROM");
return;
}

/* new firmware has to remove the update file */
vfs_file_from_buffer(RIOTBOOT_VFS_UPDATE_FILE,
RIOTBOOT_VFS_BACKUP_FILE, sizeof(RIOTBOOT_VFS_BACKUP_FILE));

/* clear pages */
for (unsigned i = flashpage_page((void *)(uintptr_t)SLOT0_OFFSET); i <= last_page; ++i) {
DEBUG("erase page %u\n", i);
flashpage_erase(i);
}

DEBUG("write %lu bytes\n", size);
fd = vfs_open(file, O_RDONLY, 0);

/* flash image */
do {
res = vfs_read(fd, buffer, sizeof(buffer));
flashpage_write(dst, buffer, res);
dst += res;
} while (res > 0);

DEBUG_PUTS("done.");

vfs_close(fd);
}

void kernel_init(void)
{
DEBUG_PUTS("riotboot VFS");

extern void auto_init(void);
auto_init();

/* get file to flash */
char update_file[64];
if (vfs_file_to_buffer(RIOTBOOT_VFS_UPDATE_FILE, update_file, sizeof(update_file)) > 0) {
_flash_image(update_file);
}
DEBUG("jump to 0x%x\n", SLOT0_OFFSET);
cpu_jump_to_image(SLOT0_OFFSET);

/* serious trouble! nothing to boot */
while (1) {}
}

NORETURN void core_panic(core_panic_t crash_code, const char *message)
{
(void)crash_code;
(void)message;
while (1) {}
}
13 changes: 13 additions & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,19 @@ ifneq (,$(filter riotboot_serial, $(USEMODULE)))
USEMODULE += checksum
endif

ifneq (,$(filter riotboot_vfs, $(USEMODULE)))
USEMODULE += riotboot
USEMODULE += vfs
USEMODULE += vfs_util
FEATURES_REQUIRED += periph_flashpage
# cpu_get_image_baseaddr() only implemented on Cortex-M
FEATURES_REQUIRED += cpu_core_cortexm

ifneq (1, $(RIOTBOOT_BUILD))
ROM_OFFSET = $(RIOTBOOT_LEN)
endif
endif

ifneq (,$(filter riotboot_reset, $(USEMODULE)))
USEMODULE += riotboot
USEMODULE += usb_board_reset
Expand Down
4 changes: 4 additions & 0 deletions sys/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ ifneq (,$(filter riotboot,$(FEATURES_USED)))
include $(RIOTBASE)/sys/riotboot/Makefile.include
endif

ifneq (,$(filter riotboot_vfs,$(USEMODULE)))
include $(RIOTBASE)/sys/riotboot/Makefile.include
endif

ifneq (,$(filter skald, $(USEMODULE)))
include $(RIOTBASE)/sys/net/ble/skald/Makefile.include
endif
Expand Down