From 41869a6534400090ce61111aa79398513462b24f Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Sun, 5 Feb 2017 21:07:20 +0100 Subject: Add boot data support to rockbox. Bootdata is a special location in the Firmware marked by a magic header The bootloader is able to copy information to the firmware by locating this struct and passing data to the firmware when it is loaded but before it is actually executed Data is verified by a crc of the bootdata Change-Id: Ib3d78cc0c3a9d47d6fe73be4747a11b7ad6f0a9e --- firmware/common/rb-loader.c | 55 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'firmware/common') diff --git a/firmware/common/rb-loader.c b/firmware/common/rb-loader.c index 10807f9c96..82b636d451 100644 --- a/firmware/common/rb-loader.c +++ b/firmware/common/rb-loader.c @@ -25,6 +25,54 @@ #include "rb-loader.h" #include "loader_strerror.h" +#if defined(HAVE_BOOTDATA) +#include "bootdata.h" +#include "crc32.h" + +/* Write boot data into location marked by magic header + * buffer is already loaded with the firmware image + * we just need to find the location and write + * data into the payload along with the crc + * for later verification and use. + * Returns payload len on success, + * On error returns EKEY_NOT_FOUND + */ +static int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) +{ + struct boot_data_t bl_boot_data; + struct boot_data_t *fw_boot_data = NULL; + int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); + int payload_len = EKEY_NOT_FOUND; + + /* search for boot data header prior to search_len */ + for(int i = 0;i < search_len;i++) + { + fw_boot_data = (struct boot_data_t*) &buf[i]; + if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || + fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) + continue; + /* 0 fill bootloader struct then add our data */ + memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); + bl_boot_data.boot_volume = boot_volume; + /* 0 fill payload region in firmware */ + memset(fw_boot_data->payload, 0, fw_boot_data->length); + /* determine maximum bytes we can write to firmware + BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ + payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); + /* write payload size back to firmware struct */ + fw_boot_data->length = payload_len; + /* copy data to firmware bootdata struct */ + memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); + /* calculate and write the crc for the payload */ + fw_boot_data->crc = crc_32(fw_boot_data->payload, + payload_len, + 0xffffffff); + break; + + } + return payload_len; +} +#endif /* HAVE_BOOTDATA */ /* Load firmware image in a format created by add method of tools/scramble * on success we return size loaded image * on error we return negative value which can be deciphered by means @@ -105,11 +153,14 @@ int load_firmware(unsigned char* buf, const char* firmware, int buffer_size) ret = EBAD_CHKSUM; goto end; } - +#ifdef HAVE_BOOTDATA + /* 0 is the default boot volume */ + write_bootdata(buf, ret, 0); +#endif ret = len; + end: close(fd); return ret; } - -- cgit v1.2.3