summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-03-07 11:53:40 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-03-11 10:58:20 -0500
commit7fa48faeb55fb43b6a4e727d0abd104b267c89a4 (patch)
tree4f3a735bc72009dc100045c8964d937be1cce7e4 /firmware/target
parent439b4e8bcad57fac53f4286033f431e7e9df6546 (diff)
downloadrockbox-7fa48faeb55fb43b6a4e727d0abd104b267c89a4.tar.gz
rockbox-7fa48faeb55fb43b6a4e727d0abd104b267c89a4.zip
multiboot: Refactor duplicated functions to a separate file
The implementation of write_bootdata() and get_redirect_dir() was copied verbatim in two different places, obviously a bad thing for maintainability. This moves them to a new file multiboot.c as they are only used for multiboot. Change-Id: Id0279216e4dd019f8bf612a81d3835eff010e506
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/pp/mi4-loader.c89
1 files changed, 1 insertions, 88 deletions
diff --git a/firmware/target/arm/pp/mi4-loader.c b/firmware/target/arm/pp/mi4-loader.c
index 0104496e9d..f609e3ff7a 100644
--- a/firmware/target/arm/pp/mi4-loader.c
+++ b/firmware/target/arm/pp/mi4-loader.c
@@ -30,96 +30,9 @@
30#include "crc32.h" 30#include "crc32.h"
31#include "file.h" 31#include "file.h"
32#if defined(HAVE_BOOTDATA) 32#if defined(HAVE_BOOTDATA)
33#include "system.h" 33#include "multiboot.h"
34#include "bootdata.h"
35
36/* Write bootdata into location in FIRMWARE marked by magic header
37 * Assumes buffer is already loaded with the firmware image
38 * We just need to find the location and write data into the
39 * payload region along with the crc for later verification and use.
40 * Returns payload len on success,
41 * On error returns EKEY_NOT_FOUND
42 */
43int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume)
44{
45 struct boot_data_t bl_boot_data;
46 struct boot_data_t *fw_boot_data = NULL;
47 int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t);
48 int payload_len = EKEY_NOT_FOUND;
49
50 /* search for boot data header prior to search_len */
51 for(int i = 0;i < search_len;i++)
52 {
53 fw_boot_data = (struct boot_data_t*) &buf[i];
54 if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 ||
55 fw_boot_data->magic[1] != BOOT_DATA_MAGIC1)
56 continue;
57
58 memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE);
59 bl_boot_data.boot_volume = boot_volume;
60
61 memset(fw_boot_data->payload, 0, fw_boot_data->length);
62 /* determine maximum bytes we can write to firmware
63 BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */
64 payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length);
65 fw_boot_data->length = payload_len;
66 /* copy data to FIRMWARE bootdata struct */
67 memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len);
68 /* crc will be used within the firmware to check validity of bootdata */
69 fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff);
70 break;
71
72 }
73 return payload_len;
74}
75#endif /* HAVE_BOOTDATA */ 34#endif /* HAVE_BOOTDATA */
76 35
77#ifdef HAVE_MULTIBOOT /* defined by config.h */
78/* Check in root of this <volume> for rockbox_main.<playername>
79 * if this file empty or there is a single slash '/'
80 * buf = '<volume#>/<rootdir>/<firmware(name)>\0'
81 * If instead '/<*DIRECTORY*>' is supplied
82 * addpath will be set to this DIRECTORY buf =
83 * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0'
84 * On error returns Negative number or 0
85 * On success returns bytes from snprintf
86 * and generated path will be placed in buf
87 * note: if supplied buffer is too small return will be
88 * the number of bytes that would have been written
89 */
90int get_redirect_dir(char* buf, int buffer_size, int volume,
91 const char* rootdir, const char* firmware)
92{
93 int fd;
94 int f_offset;
95 char add_path[MAX_PATH];
96 /* Check in root of volume for rockbox_main.<playername> redirect */
97 snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume);
98 fd = open(add_path, O_RDONLY);
99 if (fd < 0)
100 return EFILE_NOT_FOUND;
101
102 /*clear add_path for re-use*/
103 memset(add_path, 0, sizeof(add_path));
104 f_offset = read(fd, add_path,sizeof(add_path));
105 close(fd);
106
107 for(int i = f_offset - 1;i > 0; i--)
108 {
109 /* strip control chars < SPACE or all if path doesn't start with '/' */
110 if (add_path[i] < 0x20 || add_path[0] != '/')
111 add_path[i] = '\0';
112 }
113 /* if '/add_path' is specified in rockbox_main.<playername>
114 path is /<vol#>/add_path/rootdir/firmwarename
115 if add_path is empty or '/' is missing from beginning
116 path is /<vol#>/rootdir/firmwarename
117 */
118 return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path,
119 rootdir, firmware);
120}
121#endif /* HAVE_MULTIBOOT */
122
123static inline unsigned int le2int(unsigned char* buf) 36static inline unsigned int le2int(unsigned char* buf)
124{ 37{
125 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 38 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];