summaryrefslogtreecommitdiff
path: root/firmware/include/dircache_redirect.h
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-12-22 20:31:06 +0000
committerAidan MacDonald <amachronic@protonmail.com>2024-03-31 16:57:19 +0100
commitdc9d354ed22b4c6230c6bfe885e8a3d2519b1285 (patch)
treeae7e82354a3599bf3bb24cc25b341ba94d235375 /firmware/include/dircache_redirect.h
parent6ffd42548bf10cda13a01555ff4fa56d4213cdf2 (diff)
downloadrockbox-dc9d354ed22b4c6230c6bfe885e8a3d2519b1285.tar.gz
rockbox-dc9d354ed22b4c6230c6bfe885e8a3d2519b1285.zip
multiboot: Add v1 boot protocol
v1 passes the drive and partition number of the boot volume instead of using the volume number. The volume number isn't reliable because the same filesystem might get a different volume number once the firmware is loaded, which will cause the firmware to use the wrong root volume and fail to locate the correct .rockbox directory. Using drive and partition numbers avoids this issue because drive numbering is fixed and determined by the target. Change-Id: I7e68b892d9424a1f686197a6122e139b438e5f7e
Diffstat (limited to 'firmware/include/dircache_redirect.h')
-rw-r--r--firmware/include/dircache_redirect.h43
1 files changed, 36 insertions, 7 deletions
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h
index d4d72978c0..32e441c5b3 100644
--- a/firmware/include/dircache_redirect.h
+++ b/firmware/include/dircache_redirect.h
@@ -136,6 +136,41 @@ static inline void fileop_onsync_internal(struct filestr_base *stream)
136#endif 136#endif
137} 137}
138 138
139#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER)
140static inline bool multiboot_is_boot_volume(int volume)
141{
142 if (boot_data.version == 0)
143 {
144 /*
145 * Version 0 bootloaders just pass the volume number, but that's
146 * dynamically assigned and sometimes differs by the time we get
147 * into the firmware. So we can't rely on the volume passed by
148 * the bootloader.
149 */
150#if CONFIG_CPU == X1000
151 /* The affected X1000 players only have one drive to begin with */
152 return volume_drive(volume) == 0;
153#else
154 /* FIXME: Anything else that can get here is a Sansa. */
155 return volume_drive(volume) == boot_data.boot_volume ||
156 volume == boot_data.boot_volume;
157#endif
158 }
159
160 if (boot_data.version == 1)
161 {
162 /*
163 * Since version 1 the bootloader passes drive and partition
164 * number which unambiguously identifies the boot volume.
165 */
166 return volume_drive(volume) == boot_data.boot_drive &&
167 volume_partition(volume) == boot_data.boot_partition;
168 }
169
170 return false;
171}
172#endif
173
139static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) 174static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
140{ 175{
141#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) 176#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER)
@@ -148,13 +183,7 @@ static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
148 /* we need to mount the drive before we can access it */ 183 /* we need to mount the drive before we can access it */
149 root_mount_path(path, 0); /* root could be different folder don't hide */ 184 root_mount_path(path, 0); /* root could be different folder don't hide */
150 185
151/*BUGFIX bootloader is less selective about which drives it will mount -- revisit */ 186 if (multiboot_is_boot_volume(IF_MV_VOL(volume)))
152#if defined(HAVE_MULTIDRIVE) && (NUM_VOLUMES_PER_DRIVE == 1)
153 if (volume_drive(volume) == boot_data.boot_volume
154 || volume == boot_data.boot_volume)
155#else
156 if (volume == boot_data.boot_volume) /* boot volume contained in uint8_t payload */
157#endif
158 { 187 {
159 int rtlen = get_redirect_dir(rtpath, sizeof(rtpath), volume, "", ""); 188 int rtlen = get_redirect_dir(rtpath, sizeof(rtpath), volume, "", "");
160 while (rtlen > 0 && rtpath[--rtlen] == PATH_SEPCH) 189 while (rtlen > 0 && rtpath[--rtlen] == PATH_SEPCH)