summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */