diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-12-22 20:31:06 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2024-03-31 16:57:19 +0100 |
commit | dc9d354ed22b4c6230c6bfe885e8a3d2519b1285 (patch) | |
tree | ae7e82354a3599bf3bb24cc25b341ba94d235375 /firmware/include | |
parent | 6ffd42548bf10cda13a01555ff4fa56d4213cdf2 (diff) | |
download | rockbox-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')
-rw-r--r-- | firmware/include/dircache_redirect.h | 43 |
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) | ||
140 | static 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 | |||
139 | static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) | 174 | static 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) |