diff options
author | William Wilgus <me.theuser@yahoo.com> | 2017-02-05 21:07:20 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-10-29 17:50:59 +0100 |
commit | 41869a6534400090ce61111aa79398513462b24f (patch) | |
tree | 08a69dfeaf7cb8cf9e64c903616240c43770df0c /firmware/common | |
parent | 60e5cd72766ace0d35f2cf7a3d4798d8c2e848bd (diff) |
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
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/rb-loader.c | 55 |
1 files changed, 53 insertions, 2 deletions
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; } - |