mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
dist/tools: add genhdr tool to generate RIOT image headers
In order to use the RIOT bootloader (riotboot) a header needs to be created and placed before the firmware. This tool generates such a header with the expected information by the bootloader. Co-authored-by: Kaspar Schleiser <kaspar@schleiser.de>
This commit is contained in:
parent
2df0abfd70
commit
a638f31bce
39
dist/tools/riotboot_gen_hdr/Makefile
vendored
Normal file
39
dist/tools/riotboot_gen_hdr/Makefile
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
RIOTBASE := ../../..
|
||||
RIOT_INCLUDE := $(RIOTBASE)/sys/include
|
||||
RIOT_CORE_INC := $(RIOTBASE)/core/include
|
||||
NATIVE_INCLUDE := $(RIOTBASE)/cpu/native/include
|
||||
COMMON_SRC := common.c
|
||||
COMMON_HDR := common.h
|
||||
|
||||
RIOT_HDR_SRC := \
|
||||
$(RIOTBASE)/sys/checksum/fletcher32.c \
|
||||
$(RIOTBASE)/sys/riotboot/hdr.c
|
||||
|
||||
RIOT_HDR_HDR := $(RIOT_INCLUDE)/riotboot/hdr.h \
|
||||
$(RIOT_INCLUDE)/checksum/fletcher32.h \
|
||||
$(RIOTBASE)/core/include/byteorder.h
|
||||
|
||||
GENHDR_SRC := $(COMMON_SRC) $(RIOT_HDR_SRC) \
|
||||
main.c genhdr.c
|
||||
|
||||
GENHDR_HDR := $(COMMON_HDR) $(RIOT_HDR_HDR)
|
||||
|
||||
CFLAGS += -g -I. -O3 -Wall -Wextra -pedantic -std=c99
|
||||
|
||||
ifeq ($(QUIET),1)
|
||||
Q=@
|
||||
else
|
||||
Q=
|
||||
endif
|
||||
|
||||
all: bin/genhdr
|
||||
|
||||
bin/:
|
||||
$(Q)mkdir -p bin
|
||||
|
||||
bin/genhdr: $(GENHDR_HDR) $(GENHDR_SRC) Makefile | bin/
|
||||
$(Q)$(CC) $(CFLAGS) -I$(RIOT_INCLUDE) -I$(RIOT_CORE_INC) \
|
||||
-I$(NATIVE_INCLUDE) $(GENHDR_SRC) -o $@
|
||||
|
||||
clean:
|
||||
$(Q)rm -rf bin/
|
39
dist/tools/riotboot_gen_hdr/common.c
vendored
Normal file
39
dist/tools/riotboot_gen_hdr/common.c
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License v2. See the file LICENSE for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Common tools for RIOT images header generation
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
31
dist/tools/riotboot_gen_hdr/common.h
vendored
Normal file
31
dist/tools/riotboot_gen_hdr/common.h
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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
|
||||
#define COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Write len bytes of a given buffer into a file
|
||||
*
|
||||
* @param[out] filename name of the file to be written
|
||||
* @param[in] buf a pointer to the buffer which needs to be written
|
||||
* @param[in] len the number of bytes from buf to be written
|
||||
*
|
||||
*/
|
||||
int to_file(const char *filename, void *buf, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_H */
|
114
dist/tools/riotboot_gen_hdr/genhdr.c
vendored
Normal file
114
dist/tools/riotboot_gen_hdr/genhdr.c
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Inria
|
||||
* 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License v2. See the file LICENSE for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "riotboot/hdr.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @brief Alignment required to set VTOR in Cortex-M0+/3/4/7
|
||||
*/
|
||||
#define HDR_ALIGN (256)
|
||||
|
||||
static void populate_hdr(riotboot_hdr_t *hdr, uint32_t ver, uint32_t addr)
|
||||
{
|
||||
/* ensure the buffer and header have 0's */
|
||||
memset(hdr, '\0', sizeof(riotboot_hdr_t));
|
||||
|
||||
/* Generate image header */
|
||||
hdr->magic_number = RIOTBOOT_MAGIC;
|
||||
hdr->version = ver;
|
||||
hdr->start_addr = addr;
|
||||
|
||||
/* calculate header checksum */
|
||||
hdr->chksum = riotboot_hdr_checksum(hdr);
|
||||
}
|
||||
|
||||
int genhdr(int argc, char *argv[])
|
||||
{
|
||||
const char generate_usage[] = "<IMG_BIN> <APP_VER> <START_ADDR> <HDR_LEN> <outfile|->";
|
||||
|
||||
/* riotboot_hdr buffer */
|
||||
uint8_t *hdr_buf;
|
||||
|
||||
/* arguments storage variables */
|
||||
long app_ver_arg = 0;
|
||||
long start_addr_arg = 0;
|
||||
long hdr_len_arg = 0;
|
||||
|
||||
/* header variables */
|
||||
size_t hdr_len = 0;
|
||||
uint32_t app_ver = 0;
|
||||
uint32_t start_addr = 0;
|
||||
|
||||
/* helpers */
|
||||
errno = 0;
|
||||
char *p;
|
||||
|
||||
if (argc < 6) {
|
||||
fprintf(stderr, "usage: genhdr generate %s\n", generate_usage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
app_ver_arg = strtol(argv[2], &p, 0);
|
||||
if (errno != 0 || *p != '\0' || app_ver_arg > UINT32_MAX) {
|
||||
fprintf(stderr, "Error: APP_VER not valid!\n");
|
||||
}
|
||||
else {
|
||||
app_ver = app_ver_arg;
|
||||
}
|
||||
|
||||
start_addr_arg = strtol(argv[3], &p, 0);
|
||||
if (errno != 0 || *p != '\0' || start_addr_arg > UINT32_MAX) {
|
||||
fprintf(stderr, "Error: START_ADDR not valid!\n");
|
||||
}
|
||||
else {
|
||||
start_addr = start_addr_arg;
|
||||
}
|
||||
|
||||
hdr_len_arg = strtol(argv[4], &p, 0);
|
||||
if (errno != 0 || *p != '\0' || hdr_len_arg % HDR_ALIGN || hdr_len_arg > UINT32_MAX) {
|
||||
fprintf(stderr, "Error: HDR_LEN not valid!\n");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
hdr_len = hdr_len_arg;
|
||||
}
|
||||
|
||||
/* prepare a 0 initialised buffer for riotboot_hdr_t */
|
||||
hdr_buf = calloc(1, hdr_len);
|
||||
if (hdr_buf == NULL) {
|
||||
fprintf(stderr, "Error: not enough memory!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
populate_hdr((riotboot_hdr_t*)hdr_buf, app_ver, start_addr);
|
||||
|
||||
/* Write the header */
|
||||
if (!to_file(argv[5], hdr_buf, hdr_len)) {
|
||||
fprintf(stderr, "Error: cannot write output\n");
|
||||
free(hdr_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(hdr_buf);
|
||||
|
||||
return 0;
|
||||
}
|
36
dist/tools/riotboot_gen_hdr/main.c
vendored
Normal file
36
dist/tools/riotboot_gen_hdr/main.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License v2. See the file LICENSE for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Header generation tool for RIOT firmware images
|
||||
*
|
||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int genhdr(int argc, char *argv[]);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *usage = "genhdr generate [args]";
|
||||
|
||||
if (argc < 2) {
|
||||
goto usage;
|
||||
}
|
||||
else if (!strcmp(argv[1], "generate")) {
|
||||
return genhdr(argc - 1, &argv[1]);
|
||||
}
|
||||
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s\n", usage);
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user