summaryrefslogtreecommitdiffstats
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
parent60e5cd72766ace0d35f2cf7a3d4798d8c2e848bd (diff)
downloadrockbox-41869a6534400090ce61111aa79398513462b24f.tar.gz
rockbox-41869a6534400090ce61111aa79398513462b24f.tar.bz2
rockbox-41869a6534400090ce61111aa79398513462b24f.zip
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
-rw-r--r--apps/debug_menu.c30
-rw-r--r--firmware/common/rb-loader.c55
-rw-r--r--firmware/export/bootdata.h84
-rw-r--r--firmware/export/config/creativezen.h2
-rw-r--r--firmware/export/config/creativezenxfi2.h2
-rw-r--r--firmware/export/config/creativezenxfi3.h2
-rw-r--r--firmware/export/config/samsungypz5.h2
-rw-r--r--firmware/export/config/sansafuzeplus.h2
-rw-r--r--firmware/export/config/sonynwze360.h2
-rw-r--r--firmware/export/config/sonynwze370.h2
-rw-r--r--firmware/target/arm/imx233/crt0.S9
11 files changed, 190 insertions, 2 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 4947f30695..0a1ceee2e0 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -129,6 +129,10 @@
#include "talk.h"
+#if defined(HAVE_BOOTDATA) && !defined(SIMULATOR)
+#include "bootdata.h"
+#endif
+
static const char* threads_getname(int selected_item, void *data,
char *buffer, size_t buffer_len)
{
@@ -2539,7 +2543,30 @@ static bool dbg_skin_engine(void)
}
#endif
+#if defined(HAVE_BOOTDATA) && !defined(SIMULATOR)
+static bool dbg_boot_data(void)
+{
+ unsigned int crc = 0;
+ struct simplelist_info info;
+ info.scroll_all = true;
+ simplelist_info_init(&info, "Boot data", 1, NULL);
+ simplelist_set_line_count(0);
+ simplelist_addline("Magic: %.8s", boot_data.magic);
+ simplelist_addline("Length: %lu", boot_data.length);
+ simplelist_addline("CRC: %lx", boot_data.crc);
+ crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff);
+ (crc == boot_data.crc) ? simplelist_addline("CRC: OK!") :
+ simplelist_addline("CRC: BAD");
+ for (unsigned i = 0; i < boot_data.length; i += 4)
+ {
+ simplelist_addline("%02x: %02x %02x %02x %02x", i, boot_data.payload[i],
+ boot_data.payload[i+1], boot_data.payload[i+2], boot_data.payload[i+3]);
+ }
+ info.hide_selection = true;
+ return simplelist_show_list(&info);
+}
+#endif
/****** The menu *********/
static const struct {
unsigned char *desc; /* string or ID */
@@ -2652,6 +2679,9 @@ static const struct {
{"Debug scrollwheel", dbg_scrollwheel },
#endif
{"Talk engine stats", dbg_talk },
+#if defined(HAVE_BOOTDATA) && !defined(SIMULATOR)
+ {"Boot data", dbg_boot_data },
+#endif
};
static int menu_action_callback(int btn, struct gui_synclist *lists)
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;
}
-
diff --git a/firmware/export/bootdata.h b/firmware/export/bootdata.h
new file mode 100644
index 0000000000..322d50c20d
--- /dev/null
+++ b/firmware/export/bootdata.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2017 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __RB_BOOTDATA__
+#define __RB_BOOTDATA__
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+/* /!\ This file can be included in assembly files /!\ */
+
+/** The boot data will be filled by the bootloader with information that might
+ * be relevant for Rockbox. The bootloader will search for the structure using
+ * the magic header within the first BOOT_DATA_SEARCH_SIZE bytes of the binary.
+ * Typically, this structure should be as close as possible to the entry point */
+
+/* Search size for the data structure after entry point */
+#define BOOT_DATA_SEARCH_SIZE 1024
+
+#define BOOT_DATA_MAGIC0 ('r' | 'b' << 8 | 'm' << 16 | 'a' << 24)
+#define BOOT_DATA_MAGIC1 ('g' | 'i' << 8 | 'c' << 16 | '!' << 24)
+
+/* maximum size of payload */
+#define BOOT_DATA_PAYLOAD_SIZE 4
+
+#ifndef __ASSEMBLER__
+/* This is the C structure */
+struct boot_data_t
+{
+ union
+ {
+ uint32_t crc; /* crc of payload data (CRC32 with 0xffffffff for initial value) */
+ uint32_t magic[2]; /* BOOT_DATA_MAGIC0/1 */
+ };
+
+ uint32_t length; /* length of the payload */
+
+ /* add fields here */
+ union
+ {
+ struct
+ {
+ uint8_t boot_volume;
+ };
+ uint8_t payload[BOOT_DATA_PAYLOAD_SIZE];
+ };
+} __attribute__((packed));
+
+#if !defined(BOOTLOADER)
+extern struct boot_data_t boot_data;
+#endif
+#else /* __ASSEMBLER__ */
+
+/* This assembler macro implements an empty boot structure with just the magic
+ * string */
+.macro put_boot_data_here
+.global boot_data
+boot_data:
+ .word BOOT_DATA_MAGIC0
+ .word BOOT_DATA_MAGIC1
+ .word BOOT_DATA_PAYLOAD_SIZE
+ .space BOOT_DATA_PAYLOAD_SIZE, 0xff /* payload, initialised with value 0xff */
+.endm
+
+#endif
+
+#endif /* __RB_BOOTDATA__ */
diff --git a/firmware/export/config/creativezen.h b/firmware/export/config/creativezen.h
index 3667142791..0033b7d4eb 100644
--- a/firmware/export/config/creativezen.h
+++ b/firmware/export/config/creativezen.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 90
#define MODEL_NAME "Creative Zen"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/creativezenxfi2.h b/firmware/export/config/creativezenxfi2.h
index 5b275b1de8..3945311e29 100644
--- a/firmware/export/config/creativezenxfi2.h
+++ b/firmware/export/config/creativezenxfi2.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 82
#define MODEL_NAME "Creative Zen X-Fi2"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/creativezenxfi3.h b/firmware/export/config/creativezenxfi3.h
index 0503035914..d72b41d608 100644
--- a/firmware/export/config/creativezenxfi3.h
+++ b/firmware/export/config/creativezenxfi3.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 83
#define MODEL_NAME "Creative Zen X-Fi3"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/samsungypz5.h b/firmware/export/config/samsungypz5.h
index 08b607741c..882acc2a6c 100644
--- a/firmware/export/config/samsungypz5.h
+++ b/firmware/export/config/samsungypz5.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 84
#define MODEL_NAME "Samsung YP-Z5"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h
index 03d6c00b2e..af5235a6c3 100644
--- a/firmware/export/config/sansafuzeplus.h
+++ b/firmware/export/config/sansafuzeplus.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 72
#define MODEL_NAME "Sandisk Sansa Fuze+"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/sonynwze360.h b/firmware/export/config/sonynwze360.h
index dc466ec797..a25e95d274 100644
--- a/firmware/export/config/sonynwze360.h
+++ b/firmware/export/config/sonynwze360.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 89
#define MODEL_NAME "Sony NWZ-E360 series"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/export/config/sonynwze370.h b/firmware/export/config/sonynwze370.h
index 0f88d98b58..2ed87f2f1b 100644
--- a/firmware/export/config/sonynwze370.h
+++ b/firmware/export/config/sonynwze370.h
@@ -8,6 +8,8 @@
/* For Rolo and boot loader */
#define MODEL_NUMBER 88
#define MODEL_NAME "Sony NWZ-E370/E380 series"
+/* Define if boot data from bootloader has been enabled for the target */
+#define HAVE_BOOTDATA
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
index 5e1720c7c9..8db8400dbf 100644
--- a/firmware/target/arm/imx233/crt0.S
+++ b/firmware/target/arm/imx233/crt0.S
@@ -21,6 +21,10 @@
#include "config.h"
#include "cpu.h"
+#if defined(HAVE_BOOTDATA) && !defined(BOOTLOADER)
+#include "bootdata.h"
+#endif
+
.section .vectors,"ax",%progbits
.code 32
/* most handlers are in DRAM which is too far away for a relative jump */
@@ -165,6 +169,11 @@ remap:
1:
b 1b
+#if defined(HAVE_BOOTDATA) && !defined(BOOTLOADER)
+/* boot data structure */
+put_boot_data_here
+#endif
+
/* Cache-align interrupt stacks */
.balign 32
/* 256 words of IRQ stack */