Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
41c8ccc
sys/hashes/sha256: add missing unistd.h include
kaspar030 Jun 16, 2017
e76031b
riotboot: introduce riot-based minimal bootloader
kaspar030 Jun 15, 2017
d7523e8
sys/firmware: initial import of firmware management functions
kaspar030 Jun 16, 2017
1a6c925
dist/tools/firmware: initial import of firmware metadata tools
kaspar030 Jun 16, 2017
9ee8444
cpu/cortexm_common: set MSP instead of PSP in cpu_jump_to_image()
kaspar030 Oct 5, 2017
6806085
edbg: add FLASH_ADDR as offset, don't erase before flash
kaspar030 Feb 7, 2018
cbf324a
cpu/cortexm: change rom offset logic in cortexm.ld
kaspar030 Feb 7, 2018
17d5596
boards/samr21-xpro: add riotboot configuration
kaspar030 Feb 7, 2018
09a6a3d
sys/ota: introduce CoAP OTA module
kaspar030 Mar 14, 2018
d1f54c5
examples/ota: initial commit of OTA example
kaspar030 Mar 14, 2018
a885007
fixup! riotboot: introduce riot-based minimal bootloader
kaspar030 Apr 9, 2018
05c17e8
fixup! cpu/cortexm: change rom offset logic in cortexm.ld
kaspar030 Apr 10, 2018
c01eb23
fixup! dist/tools/firmware: initial import of firmware metadata tools
kaspar030 Apr 10, 2018
16dfec7
fixup! dist/tools/firmware: initial import of firmware metadata tools
kaspar030 Apr 10, 2018
58887f4
fixup! dist/tools/firmware: initial import of firmware metadata tools
kaspar030 Apr 10, 2018
5e35628
fixup! dist/tools/firmware: initial import of firmware metadata tools
kaspar030 Apr 10, 2018
3ab924b
fixup! examples/ota: initial commit of OTA example
kaspar030 Apr 10, 2018
ff39a89
fixup! sys/firmware: initial import of firmware management functions
kaspar030 Apr 10, 2018
11c96f7
fixup! sys/firmware: initial import of firmware management functions
kaspar030 Apr 10, 2018
719d0f9
fixup! sys/ota: introduce CoAP OTA module
kaspar030 Apr 10, 2018
7ac7411
fixup! fixup! examples/ota: initial commit of OTA example
kaspar030 Apr 11, 2018
49788a0
fixup! fixup! riotboot: introduce riot-based minimal bootloader
kaspar030 Apr 11, 2018
1bb4fe0
fixup! sys/firmware: initial import of firmware management functions
kaspar030 Apr 11, 2018
0ab298f
fixup! fixup! fixup! riotboot: introduce riot-based minimal bootloader
kaspar030 Apr 23, 2018
d2ad1a0
firmware: don't depend on sizeof(firmware_metadata_t)
bergzand Apr 20, 2018
a122045
Split update into firmware_simple and firmware_flashwrite
bergzand Apr 24, 2018
1087b6d
firmware: remove metadata_type from struct
bergzand May 2, 2018
2ac74b3
sys/firmware: some updates
kaspar030 Jun 1, 2018
6a0ec11
sys/firmware: remove FIRMWARE_NUM_SLOTS, use firmware_num_slots
kaspar030 Jun 1, 2018
d4ca843
sys: firmware_flashwrite: fix log message prefixes
kaspar030 Jun 1, 2018
143db71
sys/firmware: simple: fix log prefix
kaspar030 Jun 1, 2018
714ba81
sys: firmware_simple: add size check
kaspar030 Jun 1, 2018
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
21 changes: 21 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,27 @@ ifneq (,$(filter uuid,$(USEMODULE)))
USEMODULE += random
endif

ifneq (,$(RIOTBOOT_SLOT0_SIZE))
FEATURES_PROVIDED += riotboot
endif

ifneq (,$(filter ota_%,$(USEMODULE)))
USEMODULE += ota
endif

ifneq (,$(filter ota_coap,$(USEMODULE)))
USEMODULE += firmware
USEMODULE += nanocoap
endif

ifneq (,$(filter firmware,$(USEMODULE)))
USEMODULE += checksum
USEMODULE += hashes
USEPKG += tweetnacl
FEATURES_REQUIRED += riotboot
FEATURES_REQUIRED += periph_flashpage
endif

# always select gpio (until explicit dependencies are sorted out)
FEATURES_OPTIONAL += periph_gpio

Expand Down
3 changes: 3 additions & 0 deletions Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,9 @@ CFLAGS += -include '$(RIOTBUILD_CONFIG_HEADER_C)'
# include mcuboot support
include $(RIOTMAKE)/mcuboot.mk

# include riotboot support
include $(RIOTMAKE)/riotboot.mk

# include Murdock helpers
include $(RIOTMAKE)/murdock.inc.mk

Expand Down
5 changes: 5 additions & 0 deletions boards/samr21-xpro/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ export CPU_MODEL = samr21g18a
# set edbg device type
EDBG_DEVICE_TYPE = atmel_cm0p

# configure riotboot slots
export RIOTBOOT_SLOT0_SIZE ?= 0x1000
export RIOTBOOT_SLOT1_SIZE ?= 0x1f800
export RIOTBOOT_SLOT2_SIZE ?= 0x1f800

include $(RIOTMAKE)/boards/sam0.inc.mk
38 changes: 38 additions & 0 deletions cpu/cortexm_common/include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,44 @@ static inline void cortexm_isr_end(void)
}
}

/**
* @brief Jumps to another image in flash
*
* This function is supposed to be called by a bootloader application.
*
* @param[in] image_address address in flash of other image
*/
static inline void cpu_jump_to_image(uint32_t image_address)
{
/* Disable IRQ */
__disable_irq();

/* set MSP */
__set_MSP(*(uint32_t*)image_address);

/* skip stack pointer */
image_address += 4;

/* load the images reset_vector address */
uint32_t destination_address = *(uint32_t*)image_address;

/* Make sure the Thumb State bit is set. */
destination_address |= 0x1;

/* Branch execution */
__asm("BX %0" :: "r" (destination_address));
}

/* The following register is only present for Cortex-M0+, -M3, -M4 and -M7 CPUs */
#if defined(CPU_ARCH_CORTEX_M0PLUS) || defined(CPU_ARCH_CORTEX_M3) || \
defined(CPU_ARCH_CORTEX_M4) || defined(CPU_ARCH_CORTEX_M4F) || \
defined(CPU_ARCH_CORTEX_M7)
static inline unsigned cpu_get_image_baseaddr(void)
{
return (unsigned)SCB->VTOR;
}
#endif

#ifdef __cplusplus
}
#endif
Expand Down
9 changes: 6 additions & 3 deletions cpu/cortexm_common/ldscripts/cortexm.ld
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2017 Inria
* 2018 Kaspar Schleiser <[email protected]>
*
*
* 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
Expand All @@ -14,16 +16,17 @@
* @brief Memory definitions for the Cortex-M family
*
* @author Francisco Acosta <[email protected]>
* @author Kaspar Schleiser <[email protected]>
*
* @}
*/

_boot_offset = DEFINED( _rom_offset ) ? _rom_offset : 0x0 ;
_rom_offset = DEFINED( _rom_offset ) ? _rom_offset : 0x0 ;

MEMORY
{
rom (rx) : ORIGIN = _rom_start_addr + _boot_offset, LENGTH = _rom_length - _boot_offset
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
rom (rx) : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _rom_length
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
}

INCLUDE cortexm_base.ld
12 changes: 12 additions & 0 deletions dist/riotboot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
APPLICATION = riotboot

BOARD ?= samr21-xpro

USEMODULE += firmware

CFLAGS += -DNDEBUG -DLOG_LEVEL=LOG_NONE
DISABLE_MODULE += auto_init

RIOTBASE ?= $(CURDIR)/../..

include $(RIOTBASE)/Makefile.include
6 changes: 6 additions & 0 deletions dist/riotboot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Overview

This folder contains a simple bootloader that allows ping-pong style
over-the-air updates.

Please see examples/ota as example.
61 changes: 61 additions & 0 deletions dist/riotboot/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

What about simply calling the parent directory bootloader ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

are you suggesting to change the name "riotboot"? there might be other bootloaders coming.

Copy link
Contributor

Choose a reason for hiding this comment

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

I still think the bootloader should be at the root of RIOT. Even if other bootlaoders come, we'll have a very hard time to integrate them into the base code, at best, they'll come as packages. Any strong reason/motivation to keep it in dist? It's not even possible to compile it/use it outside RIOT...

* Copyright (C) 2017 Kaspar Schleiser <[email protected]>
* Inria
*
* 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 bootloader
* @{
*
* @file
* @brief RIOT Bootloader
*
* @author Kaspar Schleiser <[email protected]>
* @author Francisco Acosta <[email protected]>
*
* @}
*/

#include "firmware.h"
#include "cpu.h"
#include "panic.h"

void kernel_init(void)
{
uint32_t version = 0;
uint32_t slot = 0;

/* skip slot 0 (which points to the bootloader) */
for (unsigned i = 1; i < firmware_num_slots; i++) {
firmware_metadata_t *slot_metadata = firmware_get_metadata(i);
if (firmware_validate_metadata_checksum(slot_metadata)) {
/* skip slot if metadata broken */
continue;
}
if (slot_metadata->start_addr != firmware_get_image_startaddr(i)) {
continue;
}
if (!slot || slot_metadata->version > version) {
version = slot_metadata->version;
slot = i;
}
}

if (slot) {
firmware_jump_to_slot(slot);
}

/* serious trouble! */
Copy link
Contributor

Choose a reason for hiding this comment

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

Why ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hope noone ever finds out.

Copy link
Contributor

Choose a reason for hiding this comment

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

If all the conditions to boot an image are not met, the bootloader boots nothing, which indeed, is serious trouble...

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the clarification, that I think should replace the 'serious trouble' comment for clarity. But then, in this case, why is the endless while loop required ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is intended to provide a defined error behaviour.

while (1) {}
}

NORETURN void core_panic(core_panic_t crash_code, const char *message)
{
(void)crash_code;
(void)message;
while (1) {}
}
46 changes: 46 additions & 0 deletions dist/tools/firmware/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
PKG_NAME = tweetnacl
PKG_URL = https://github.com/RIOT-OS/tweetnacl
PKG_VERSION = 7ea05c7098a16c87fa66e9166ce301666f3f2623
PKG_LICENSE = PD
PKG_BUILDDIR = bin/tweetnacl_src
GITCACHE = ../git/git-cache

RIOTBASE := ../../..
RIOT_INCLUDE := $(RIOTBASE)/sys/include
SHA256_DIR := $(RIOTBASE)/sys/hashes
SHA256_INCLUDE := $(RIOT_INCLUDE)/hashes
TWEETNACL_DIR := $(PKG_BUILDDIR)
TWEETNACL_SRC := $(TWEETNACL_DIR)/tweetnacl.c randombytes.c
TWEETNACL_HDR := $(TWEETNACL_DIR)/tweetnacl.h
COMMON_SRC := common.c
COMMON_HDR := common.h

RIOT_FIRMWARE_SRC := \
$(SHA256_DIR)/sha256.c \
$(RIOTBASE)/sys/checksum/fletcher32.c \
$(RIOTBASE)/sys/firmware/firmware.c \
$(RIOTBASE)/sys/firmware/firmware_simple.c

RIOT_FIRMWARE_HDR := $(RIOT_INCLUDE)/firmware.h \
$(RIOT_INCLUDE)/hashes/sha256.h \
$(RIOT_INCLUDE)/checksum/fletcher32.h

FIRMWARE_SRC := $(COMMON_SRC) $(TWEETNACL_SRC) $(RIOT_FIRMWARE_SRC) \
main.c verify.c genkeys.c sign.c

FIRMWARE_HDR := $(COMMON_HDR) $(RIOT_FIRMWARE_HDR)

CFLAGS += -g -I. -O3 -Wall -Wextra -pedantic -std=c99

all: bin/firmware

bin/:
mkdir -p bin

bin/firmware: git-download $(FIRMWARE_HDR) $(FIRMWARE_SRC) Makefile | bin/
$(CC) $(CFLAGS) -I$(RIOT_INCLUDE) -I$(TWEETNACL_DIR) $(FIRMWARE_SRC) -o $@

clean::
rm -rf bin/firmware

include $(RIOTBASE)/pkg/pkg.mk
92 changes: 92 additions & 0 deletions dist/tools/firmware/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (C) 2017 Kaspar Schleiser <[email protected]>
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file LICENSE for more details.
*/

#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "hashes/sha256.h"

off_t fsize(const char *filename)
{
struct stat st;

if (stat(filename, &st) == 0) {
return st.st_size;
}

return -1;
}

int to_file(const char *filename, void *buf, size_t len)
{
int fd;

if (strcmp("-", filename)) {
fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
}
else {
fd = STDOUT_FILENO;
}

if (fd > 0) {
ssize_t res = write(fd, buf, len);
close(fd);
return res == (ssize_t)len;
}
else {
return fd;
}
}

int from_file(const char *filename, void *buf, size_t len)
{
int fd = open(filename, O_RDONLY);

if (fd > 0) {
ssize_t res = read(fd, buf, len);
close(fd);
return res == (ssize_t)len;
}
else {
return fd;
}
}

ssize_t do_sha256(const char *filename, void *tgt, off_t offset)
{
sha256_context_t sha256;

sha256_init(&sha256);

ssize_t bytes_read;
ssize_t total = 0;
char buf[1024];

int fd = open(filename, O_RDONLY);
if (!fd) {
return -1;
}

if (offset) {
if (lseek(fd, offset, SEEK_SET) == -1) {
return -1;
}
}

while ((bytes_read = read(fd, buf, sizeof(buf)))) {
sha256_update(&sha256, buf, bytes_read);
total += bytes_read;
}

sha256_final(&sha256, tgt);

close(fd);

return total;
}
27 changes: 27 additions & 0 deletions dist/tools/firmware/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 Kaspar Schleiser <[email protected]>
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file LICENSE for more details.
*/

#ifndef COMMON_H
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe use a more strict header guard ? (FIRMWARE_COMMON_H ?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is a local header file. change when there's a clash?

#define COMMON_H

#include <unistd.h>
#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

off_t fsize(const char *filename);
Copy link
Contributor

Choose a reason for hiding this comment

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

Undocumented functions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

internal functions

Copy link
Contributor

@kYc0o kYc0o Apr 11, 2018

Choose a reason for hiding this comment

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

@kaspar030 you might however prefix with _ isn't it? Though would look strange in a header... I'd say if it's internal we might change its place. Isn't doxygen complaining btw?

int to_file(const char *filename, void *buf, size_t len);
int from_file(const char *filename, void *buf, size_t len);
int do_sha256(const char *filename, void *tgt, size_t offset);

#ifdef __cplusplus
} /* end extern "C" */
#endif

#endif /* COMMON_H */
Loading