diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-03-07 11:53:40 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-03-11 10:58:20 -0500 |
commit | 7fa48faeb55fb43b6a4e727d0abd104b267c89a4 (patch) | |
tree | 4f3a735bc72009dc100045c8964d937be1cce7e4 | |
parent | 439b4e8bcad57fac53f4286033f431e7e9df6546 (diff) | |
download | rockbox-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
-rw-r--r-- | apps/debug_menu.c | 1 | ||||
-rw-r--r-- | firmware/SOURCES | 4 | ||||
-rw-r--r-- | firmware/common/multiboot.c | 113 | ||||
-rw-r--r-- | firmware/common/rb-loader.c | 93 | ||||
-rw-r--r-- | firmware/export/mi4-loader.h | 22 | ||||
-rw-r--r-- | firmware/export/multiboot.h | 30 | ||||
-rw-r--r-- | firmware/include/dircache_redirect.h | 1 | ||||
-rw-r--r-- | firmware/include/rb-loader.h | 20 | ||||
-rw-r--r-- | firmware/rolo.c | 12 | ||||
-rw-r--r-- | firmware/target/arm/pp/mi4-loader.c | 89 |
10 files changed, 165 insertions, 220 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 6b76aac162..3c089df8bb 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -128,6 +128,7 @@ | |||
128 | 128 | ||
129 | #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) | 129 | #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) |
130 | #include "bootdata.h" | 130 | #include "bootdata.h" |
131 | #include "multiboot.h" | ||
131 | #include "rbpaths.h" | 132 | #include "rbpaths.h" |
132 | #include "pathfuncs.h" | 133 | #include "pathfuncs.h" |
133 | #include "rb-loader.h" | 134 | #include "rb-loader.h" |
diff --git a/firmware/SOURCES b/firmware/SOURCES index 2e2f13bbe9..812174500e 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -51,6 +51,10 @@ panic.c | |||
51 | target/hosted/rolo.c | 51 | target/hosted/rolo.c |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #if defined(HAVE_BOOTDATA) || defined(HAVE_MULTIBOOT) | ||
55 | common/multiboot.c | ||
56 | #endif | ||
57 | |||
54 | #ifdef HAVE_SDL | 58 | #ifdef HAVE_SDL |
55 | target/hosted/sdl/button-sdl.c | 59 | target/hosted/sdl/button-sdl.c |
56 | target/hosted/sdl/kernel-sdl.c | 60 | target/hosted/sdl/kernel-sdl.c |
diff --git a/firmware/common/multiboot.c b/firmware/common/multiboot.c new file mode 100644 index 0000000000..dfa6556be3 --- /dev/null +++ b/firmware/common/multiboot.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2017, 2020 by William Wilgus | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #include "system.h" | ||
22 | #include "bootdata.h" | ||
23 | #include "crc32.h" | ||
24 | #include "loader_strerror.h" | ||
25 | #include "file.h" | ||
26 | #include <string.h> | ||
27 | #include <stdio.h> | ||
28 | |||
29 | /* Write bootdata into location in FIRMWARE marked by magic header | ||
30 | * Assumes buffer is already loaded with the firmware image | ||
31 | * We just need to find the location and write data into the | ||
32 | * payload region along with the crc for later verification and use. | ||
33 | * Returns payload len on success, | ||
34 | * On error returns EKEY_NOT_FOUND | ||
35 | */ | ||
36 | int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) | ||
37 | { | ||
38 | struct boot_data_t bl_boot_data; | ||
39 | struct boot_data_t *fw_boot_data = NULL; | ||
40 | int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); | ||
41 | int payload_len = EKEY_NOT_FOUND; | ||
42 | |||
43 | /* search for boot data header prior to search_len */ | ||
44 | for(int i = 0;i < search_len;i++) | ||
45 | { | ||
46 | fw_boot_data = (struct boot_data_t*) &buf[i]; | ||
47 | if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || | ||
48 | fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) | ||
49 | continue; | ||
50 | |||
51 | memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); | ||
52 | bl_boot_data.boot_volume = boot_volume; | ||
53 | |||
54 | memset(fw_boot_data->payload, 0, fw_boot_data->length); | ||
55 | /* determine maximum bytes we can write to firmware | ||
56 | BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ | ||
57 | payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); | ||
58 | fw_boot_data->length = payload_len; | ||
59 | /* copy data to FIRMWARE bootdata struct */ | ||
60 | memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); | ||
61 | /* crc will be used within the firmware to check validity of bootdata */ | ||
62 | fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff); | ||
63 | break; | ||
64 | |||
65 | } | ||
66 | return payload_len; | ||
67 | } | ||
68 | |||
69 | #ifdef HAVE_MULTIBOOT | ||
70 | /* Check in root of this <volume> for rockbox_main.<playername> | ||
71 | * if this file empty or there is a single slash '/' | ||
72 | * buf = '<volume#>/<rootdir>/<firmware(name)>\0' | ||
73 | * If instead '/<*DIRECTORY*>' is supplied | ||
74 | * addpath will be set to this DIRECTORY buf = | ||
75 | * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' | ||
76 | * On error returns Negative number or 0 | ||
77 | * On success returns bytes from snprintf | ||
78 | * and generated path will be placed in buf | ||
79 | * note: if supplied buffer is too small return will be | ||
80 | * the number of bytes that would have been written | ||
81 | */ | ||
82 | int get_redirect_dir(char* buf, int buffer_size, int volume, | ||
83 | const char* rootdir, const char* firmware) | ||
84 | { | ||
85 | int fd; | ||
86 | int f_offset; | ||
87 | char add_path[MAX_PATH]; | ||
88 | /* Check in root of volume for rockbox_main.<playername> redirect */ | ||
89 | snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume); | ||
90 | fd = open(add_path, O_RDONLY); | ||
91 | if (fd < 0) | ||
92 | return EFILE_NOT_FOUND; | ||
93 | |||
94 | /*clear add_path for re-use*/ | ||
95 | memset(add_path, 0, sizeof(add_path)); | ||
96 | f_offset = read(fd, add_path,sizeof(add_path)); | ||
97 | close(fd); | ||
98 | |||
99 | for(int i = f_offset - 1;i > 0; i--) | ||
100 | { | ||
101 | /* strip control chars < SPACE or all if path doesn't start with '/' */ | ||
102 | if (add_path[i] < 0x20 || add_path[0] != '/') | ||
103 | add_path[i] = '\0'; | ||
104 | } | ||
105 | /* if '/add_path' is specified in rockbox_main.<playername> | ||
106 | path is /<vol#>/add_path/rootdir/firmwarename | ||
107 | if add_path is empty or '/' is missing from beginning | ||
108 | path is /<vol#>/rootdir/firmwarename | ||
109 | */ | ||
110 | return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path, | ||
111 | rootdir, firmware); | ||
112 | } | ||
113 | #endif | ||
diff --git a/firmware/common/rb-loader.c b/firmware/common/rb-loader.c index 300ba55401..e3fc90342c 100644 --- a/firmware/common/rb-loader.c +++ b/firmware/common/rb-loader.c | |||
@@ -26,96 +26,9 @@ | |||
26 | #include "loader_strerror.h" | 26 | #include "loader_strerror.h" |
27 | #include "checksum.h" | 27 | #include "checksum.h" |
28 | 28 | ||
29 | #if defined(HAVE_BOOTDATA) | 29 | #if defined(HAVE_BOOTDATA) || defined(HAVE_MULTIBOOT) |
30 | #include "bootdata.h" | 30 | #include "multiboot.h" |
31 | #include "crc32.h" | 31 | #endif |
32 | |||
33 | /* Write bootdata into location in FIRMWARE marked by magic header | ||
34 | * Assumes buffer is already loaded with the firmware image | ||
35 | * We just need to find the location and write data into the | ||
36 | * payload region along with the crc for later verification and use. | ||
37 | * Returns payload len on success, | ||
38 | * On error returns EKEY_NOT_FOUND | ||
39 | */ | ||
40 | int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) | ||
41 | { | ||
42 | struct boot_data_t bl_boot_data; | ||
43 | struct boot_data_t *fw_boot_data = NULL; | ||
44 | int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); | ||
45 | int payload_len = EKEY_NOT_FOUND; | ||
46 | |||
47 | /* search for boot data header prior to search_len */ | ||
48 | for(int i = 0;i < search_len;i++) | ||
49 | { | ||
50 | fw_boot_data = (struct boot_data_t*) &buf[i]; | ||
51 | if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || | ||
52 | fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) | ||
53 | continue; | ||
54 | |||
55 | memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); | ||
56 | bl_boot_data.boot_volume = boot_volume; | ||
57 | |||
58 | memset(fw_boot_data->payload, 0, fw_boot_data->length); | ||
59 | /* determine maximum bytes we can write to firmware | ||
60 | BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ | ||
61 | payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); | ||
62 | fw_boot_data->length = payload_len; | ||
63 | /* copy data to FIRMWARE bootdata struct */ | ||
64 | memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); | ||
65 | /* crc will be used within the firmware to check validity of bootdata */ | ||
66 | fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff); | ||
67 | break; | ||
68 | |||
69 | } | ||
70 | return payload_len; | ||
71 | } | ||
72 | #endif /* HAVE_BOOTDATA */ | ||
73 | |||
74 | #ifdef HAVE_MULTIBOOT /* defined by config.h */ | ||
75 | /* Check in root of this <volume> for rockbox_main.<playername> | ||
76 | * if this file empty or there is a single slash '/' | ||
77 | * buf = '<volume#>/<rootdir>/<firmware(name)>\0' | ||
78 | * If instead '/<*DIRECTORY*>' is supplied | ||
79 | * addpath will be set to this DIRECTORY buf = | ||
80 | * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' | ||
81 | * On error returns Negative number or 0 | ||
82 | * On success returns bytes from snprintf | ||
83 | * and generated path will be placed in buf | ||
84 | * note: if supplied buffer is too small return will be | ||
85 | * the number of bytes that would have been written | ||
86 | */ | ||
87 | int get_redirect_dir(char* buf, int buffer_size, int volume, | ||
88 | const char* rootdir, const char* firmware) | ||
89 | { | ||
90 | int fd; | ||
91 | int f_offset; | ||
92 | char add_path[MAX_PATH]; | ||
93 | /* Check in root of volume for rockbox_main.<playername> redirect */ | ||
94 | snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume); | ||
95 | fd = open(add_path, O_RDONLY); | ||
96 | if (fd < 0) | ||
97 | return EFILE_NOT_FOUND; | ||
98 | |||
99 | /*clear add_path for re-use*/ | ||
100 | memset(add_path, 0, sizeof(add_path)); | ||
101 | f_offset = read(fd, add_path,sizeof(add_path)); | ||
102 | close(fd); | ||
103 | |||
104 | for(int i = f_offset - 1;i > 0; i--) | ||
105 | { | ||
106 | /* strip control chars < SPACE or all if path doesn't start with '/' */ | ||
107 | if (add_path[i] < 0x20 || add_path[0] != '/') | ||
108 | add_path[i] = '\0'; | ||
109 | } | ||
110 | /* if '/add_path' is specified in rockbox_main.<playername> | ||
111 | path is /<vol#>/add_path/rootdir/firmwarename | ||
112 | if add_path is empty or '/' is missing from beginning | ||
113 | path is /<vol#>/rootdir/firmwarename | ||
114 | */ | ||
115 | return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path, | ||
116 | rootdir, firmware); | ||
117 | } | ||
118 | #endif /* HAVE_MULTIBOOT */ | ||
119 | 32 | ||
120 | /* loads a firmware file from supplied filename | 33 | /* loads a firmware file from supplied filename |
121 | * file opened, checks firmware size and checksum | 34 | * file opened, checks firmware size and checksum |
diff --git a/firmware/export/mi4-loader.h b/firmware/export/mi4-loader.h index f66164ec2c..adc43ebf64 100644 --- a/firmware/export/mi4-loader.h +++ b/firmware/export/mi4-loader.h | |||
@@ -21,6 +21,9 @@ | |||
21 | * | 21 | * |
22 | ****************************************************************************/ | 22 | ****************************************************************************/ |
23 | 23 | ||
24 | #ifndef __MI4_LOADER_H__ | ||
25 | #define __MI4_LOADER_H__ | ||
26 | |||
24 | #include <stdint.h> | 27 | #include <stdint.h> |
25 | 28 | ||
26 | #define MI4_HEADER_SIZE 0x200 | 29 | #define MI4_HEADER_SIZE 0x200 |
@@ -50,21 +53,4 @@ struct tea_key { | |||
50 | int load_mi4(unsigned char* buf, const char* firmware, unsigned int buffer_size); | 53 | int load_mi4(unsigned char* buf, const char* firmware, unsigned int buffer_size); |
51 | const char *mi4_strerror(int8_t errno); | 54 | const char *mi4_strerror(int8_t errno); |
52 | 55 | ||
53 | #ifdef HAVE_MULTIBOOT /* defined by config.h */ | 56 | #endif /* __MI4_LOADER_H__ */ |
54 | /* Check in root of this <volume> for rockbox_main.<playername> | ||
55 | * if this file empty or there is a single slash '/' | ||
56 | * buf = '<volume#>/<rootdir>/<firmware(name)>\0' | ||
57 | * If instead '/<*DIRECTORY*>' is supplied | ||
58 | * addpath will be set to this DIRECTORY buf = | ||
59 | * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' | ||
60 | * On error returns Negative number or 0 | ||
61 | * On success returns bytes from snprintf | ||
62 | * and generated path will be placed in buf | ||
63 | * note: if supplied buffer is too small return will be | ||
64 | * the number of bytes that would have been written | ||
65 | */ | ||
66 | |||
67 | /* TODO needs mapped back to debug_menu if root redirect ever becomes a reality */ | ||
68 | int get_redirect_dir(char* buf, int buffer_size, int volume, | ||
69 | const char* rootdir, const char* firmware); | ||
70 | #endif | ||
diff --git a/firmware/export/multiboot.h b/firmware/export/multiboot.h new file mode 100644 index 0000000000..0132b8531f --- /dev/null +++ b/firmware/export/multiboot.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2017, 2020 by William Wilgus | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #ifndef __MULTIBOOT_H__ | ||
22 | #define __MULTIBOOT_H__ | ||
23 | |||
24 | extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); | ||
25 | #ifdef HAVE_MULTIBOOT | ||
26 | extern int get_redirect_dir(char* buf, int buffer_size, int volume, | ||
27 | const char* rootdir, const char* firmware); | ||
28 | #endif | ||
29 | |||
30 | #endif /* __MULTIBOOT_H__ */ | ||
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h index c8905455f9..65b2184d2b 100644 --- a/firmware/include/dircache_redirect.h +++ b/firmware/include/dircache_redirect.h | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) | 28 | #if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) |
29 | #include "rb-loader.h" | 29 | #include "rb-loader.h" |
30 | #include "multiboot.h" | ||
30 | #include "bootdata.h" | 31 | #include "bootdata.h" |
31 | #include "crc32.h" | 32 | #include "crc32.h" |
32 | #endif | 33 | #endif |
diff --git a/firmware/include/rb-loader.h b/firmware/include/rb-loader.h index 71b6e038aa..d554ace95e 100644 --- a/firmware/include/rb-loader.h +++ b/firmware/include/rb-loader.h | |||
@@ -18,21 +18,9 @@ | |||
18 | * | 18 | * |
19 | ****************************************************************************/ | 19 | ****************************************************************************/ |
20 | 20 | ||
21 | #ifndef __RB_LOADER_H__ | ||
22 | #define __RB_LOADER_H__ | ||
23 | |||
21 | int load_firmware(unsigned char* buf, const char* firmware, int buffer_size); | 24 | int load_firmware(unsigned char* buf, const char* firmware, int buffer_size); |
22 | 25 | ||
23 | #ifdef HAVE_MULTIBOOT /* defined by config.h */ | 26 | #endif /* __RB_LOADER_H__ */ |
24 | /* Check in root of this <volume> for rockbox_main.<playername> | ||
25 | * if this file empty or there is a single slash '/' | ||
26 | * buf = '<volume#>/<rootdir>/<firmware(name)>\0' | ||
27 | * If instead '/<*DIRECTORY*>' is supplied | ||
28 | * addpath will be set to this DIRECTORY buf = | ||
29 | * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' | ||
30 | * On error returns Negative number or 0 | ||
31 | * On success returns bytes from snprintf | ||
32 | * and generated path will be placed in buf | ||
33 | * note: if supplied buffer is too small return will be | ||
34 | * the number of bytes that would have been written | ||
35 | */ | ||
36 | int get_redirect_dir(char* buf, int buffer_size, int volume, | ||
37 | const char* rootdir, const char* firmware); | ||
38 | #endif | ||
diff --git a/firmware/rolo.c b/firmware/rolo.c index f95fc4bd4d..24488e5934 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c | |||
@@ -41,23 +41,19 @@ | |||
41 | #include "loader_strerror.h" | 41 | #include "loader_strerror.h" |
42 | #if defined(MI4_FORMAT) | 42 | #if defined(MI4_FORMAT) |
43 | #include "mi4-loader.h" | 43 | #include "mi4-loader.h" |
44 | #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) | ||
45 | #include "bootdata.h" | ||
46 | #include "crc32.h" | ||
47 | extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); /*mi4-loader.c*/ | ||
48 | #endif | ||
49 | #define LOAD_FIRMWARE(a,b,c) load_mi4(a,b,c) | 44 | #define LOAD_FIRMWARE(a,b,c) load_mi4(a,b,c) |
50 | #elif defined(RKW_FORMAT) | 45 | #elif defined(RKW_FORMAT) |
51 | #include "rkw-loader.h" | 46 | #include "rkw-loader.h" |
52 | #define LOAD_FIRMWARE(a,b,c) load_rkw(a,b,c) | 47 | #define LOAD_FIRMWARE(a,b,c) load_rkw(a,b,c) |
53 | #else | 48 | #else |
54 | #include "rb-loader.h" | 49 | #include "rb-loader.h" |
50 | #define LOAD_FIRMWARE(a,b,c) load_firmware(a,b,c) | ||
51 | #endif | ||
52 | |||
55 | #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) | 53 | #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) |
54 | #include "multiboot.h" | ||
56 | #include "bootdata.h" | 55 | #include "bootdata.h" |
57 | #include "crc32.h" | 56 | #include "crc32.h" |
58 | extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); /*rb-loader.c*/ | ||
59 | #endif | ||
60 | #define LOAD_FIRMWARE(a,b,c) load_firmware(a,b,c) | ||
61 | #endif | 57 | #endif |
62 | 58 | ||
63 | #if CONFIG_CPU == AS3525v2 | 59 | #if CONFIG_CPU == AS3525v2 |
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 | */ | ||
43 | int 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 | */ | ||
90 | int 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 | |||
123 | static inline unsigned int le2int(unsigned char* buf) | 36 | static 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]; |