summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2017-02-05 21:07:20 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-10-29 17:50:59 +0100
commit41869a6534400090ce61111aa79398513462b24f (patch)
tree08a69dfeaf7cb8cf9e64c903616240c43770df0c /firmware/common
parent60e5cd72766ace0d35f2cf7a3d4798d8c2e848bd (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.c55
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;
}
-