diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2024-06-30 15:00:29 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2024-06-30 15:05:08 -0400 |
commit | 36fdd3dfed29cf6e325c12b7b21cab66dc278529 (patch) | |
tree | ac8b3edf47b57449357b3ba40e3cc258b66f4637 /bootloader | |
parent | dc7486c7de3018b78fcfeafe7a1cc5c9da168494 (diff) | |
download | rockbox-36fdd3dfed29cf6e325c12b7b21cab66dc278529.tar.gz rockbox-36fdd3dfed29cf6e325c12b7b21cab66dc278529.zip |
bootloader: Improvements for hibyos targets
* Make sure SD card is mounted prior to reading or writing
boot mode file
* If rockbox boot fails, fall back into the tools menu
* Use a 1s timeout instead of 10s if booting from previous mode
(special case for first boot)
Change-Id: I61e1ee1ee5c2a1849a2632220275ae7767fae823
Diffstat (limited to 'bootloader')
-rw-r--r-- | bootloader/rocker_linux.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/bootloader/rocker_linux.c b/bootloader/rocker_linux.c index c0cba2776c..4d095b8885 100644 --- a/bootloader/rocker_linux.c +++ b/bootloader/rocker_linux.c | |||
@@ -145,6 +145,7 @@ enum boot_mode | |||
145 | BOOT_OF, | 145 | BOOT_OF, |
146 | BOOT_COUNT, | 146 | BOOT_COUNT, |
147 | BOOT_STOP, /* power down/suspend */ | 147 | BOOT_STOP, /* power down/suspend */ |
148 | BOOT_CANARY, | ||
148 | }; | 149 | }; |
149 | 150 | ||
150 | static void display_text_center(int y, const char *text) | 151 | static void display_text_center(int y, const char *text) |
@@ -165,16 +166,17 @@ static void display_text_centerf(int y, const char *format, ...) | |||
165 | } | 166 | } |
166 | 167 | ||
167 | /* get timeout before taking action if the user doesn't touch the device */ | 168 | /* get timeout before taking action if the user doesn't touch the device */ |
168 | static int get_inactivity_tmo(void) | 169 | static int get_inactivity_tmo(int same_as_last) |
169 | { | 170 | { |
170 | #if defined(HAS_BUTTON_HOLD) | 171 | #if defined(HAS_BUTTON_HOLD) |
171 | if(button_hold()) | 172 | if(button_hold()) |
172 | return 5 * HZ; /* Inactivity timeout when on hold */ | 173 | return 5 * HZ; /* Inactivity timeout when on hold */ |
173 | else | 174 | else |
174 | #endif | 175 | #endif |
175 | return 10 * HZ; /* Inactivity timeout when not on hold */ | 176 | if (same_as_last) |
176 | 177 | return 1 * HZ; /* Timeout when mode is the same as the previous mode */ | |
177 | // XXX if booting the last selection, use a short timeout? | 178 | else |
179 | return 10 * HZ; /* Default timeout */ | ||
178 | } | 180 | } |
179 | 181 | ||
180 | /* return action on idle timeout */ | 182 | /* return action on idle timeout */ |
@@ -188,34 +190,38 @@ static enum boot_mode inactivity_action(enum boot_mode cur_selection) | |||
188 | return cur_selection; /* return last choice */ | 190 | return cur_selection; /* return last choice */ |
189 | } | 191 | } |
190 | 192 | ||
191 | /* we store the boot mode in a file in /tmp so we can reload it between 'boots' | 193 | static int mounted = 0; |
192 | * (since the mostly suspends instead of powering down) */ | ||
193 | static enum boot_mode load_boot_mode(enum boot_mode mode) | ||
194 | { | ||
195 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDONLY); | ||
196 | if(fd >= 0) | ||
197 | { | ||
198 | read(fd, &mode, sizeof(mode)); | ||
199 | close(fd); | ||
200 | } | ||
201 | return mode; | ||
202 | } | ||
203 | 194 | ||
204 | static void mount_storage(int enable) | 195 | static void mount_storage(int enable) |
205 | { | 196 | { |
206 | if (enable) { | 197 | if (enable && !mounted) { |
207 | system("/bin/mkdir -p " BASE_DIR); | 198 | system("/bin/mkdir -p " BASE_DIR); |
208 | if (system("/bin/mount /dev/mmcblk0 " BASE_DIR)) | 199 | if (system("/bin/mount /dev/mmcblk0 " BASE_DIR)) |
209 | system("/bin/mount /dev/mmcblk0p1 " BASE_DIR); | 200 | system("/bin/mount /dev/mmcblk0p1 " BASE_DIR); |
210 | // XXX possibly invoke sys_serv -> "MOUNT:MOUNT:%s %s", blkdev, mntpoint | 201 | // XXX possibly invoke sys_serv -> "MOUNT:MOUNT:%s %s", blkdev, mntpoint |
211 | } else { | 202 | } else if (!enable && mounted) { |
212 | system("/bin/unmount " BASE_DIR); | 203 | system("/bin/unmount " BASE_DIR); |
213 | // XXX possibly invoke sys_serv -> "MOUNT:UNMOUNT:%s %s", mntpoint | 204 | // XXX possibly invoke sys_serv -> "MOUNT:UNMOUNT:%s %s", mntpoint |
214 | } | 205 | } |
206 | mounted = enable; | ||
207 | } | ||
208 | |||
209 | /* we store the boot mode in a file so we can reload it between 'boots' */ | ||
210 | static enum boot_mode load_boot_mode(enum boot_mode mode) | ||
211 | { | ||
212 | mount_storage(true); | ||
213 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDONLY); | ||
214 | if(fd >= 0) | ||
215 | { | ||
216 | read(fd, &mode, sizeof(mode)); | ||
217 | close(fd); | ||
218 | } | ||
219 | return mode; | ||
215 | } | 220 | } |
216 | 221 | ||
217 | static void save_boot_mode(enum boot_mode mode) | 222 | static void save_boot_mode(enum boot_mode mode) |
218 | { | 223 | { |
224 | mount_storage(true); | ||
219 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); | 225 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); |
220 | if(fd >= 0) | 226 | if(fd >= 0) |
221 | { | 227 | { |
@@ -227,9 +233,9 @@ static void save_boot_mode(enum boot_mode mode) | |||
227 | static enum boot_mode get_boot_mode(void) | 233 | static enum boot_mode get_boot_mode(void) |
228 | { | 234 | { |
229 | /* load previous mode, or start with rockbox if none */ | 235 | /* load previous mode, or start with rockbox if none */ |
230 | enum boot_mode init_mode = load_boot_mode(BOOT_ROCKBOX); | 236 | enum boot_mode init_mode = load_boot_mode(BOOT_CANARY); |
231 | /* wait for user action */ | 237 | /* wait for user action */ |
232 | enum boot_mode mode = init_mode; | 238 | enum boot_mode mode = (init_mode == BOOT_CANARY) ? BOOT_ROCKBOX : init_mode; |
233 | int last_activity = current_tick; | 239 | int last_activity = current_tick; |
234 | #if defined(HAS_BUTTON_HOLD) | 240 | #if defined(HAS_BUTTON_HOLD) |
235 | bool hold_status = button_hold(); | 241 | bool hold_status = button_hold(); |
@@ -244,7 +250,7 @@ static enum boot_mode get_boot_mode(void) | |||
244 | return mode; | 250 | return mode; |
245 | } | 251 | } |
246 | /* inactivity detection */ | 252 | /* inactivity detection */ |
247 | int timeout = last_activity + get_inactivity_tmo(); | 253 | int timeout = last_activity + get_inactivity_tmo(init_mode == mode); |
248 | if(TIME_AFTER(current_tick, timeout)) | 254 | if(TIME_AFTER(current_tick, timeout)) |
249 | { | 255 | { |
250 | /* save last choice */ | 256 | /* save last choice */ |
@@ -314,10 +320,14 @@ static enum boot_mode get_boot_mode(void) | |||
314 | if(btn == BUTTON_SELECT) | 320 | if(btn == BUTTON_SELECT) |
315 | break; | 321 | break; |
316 | /* left/right/up/down: change mode */ | 322 | /* left/right/up/down: change mode */ |
317 | if(btn == BUTTON_LEFT || btn == BUTTON_DOWN) | 323 | if(btn == BUTTON_LEFT || btn == BUTTON_DOWN) { |
318 | mode = (mode + BOOT_COUNT - 1) % BOOT_COUNT; | 324 | mode = (mode + BOOT_COUNT - 1) % BOOT_COUNT; |
319 | if(btn == BUTTON_RIGHT || btn == BUTTON_UP) | 325 | init_mode = BOOT_CANARY; |
326 | } | ||
327 | if(btn == BUTTON_RIGHT || btn == BUTTON_UP) { | ||
320 | mode = (mode + 1) % BOOT_COUNT; | 328 | mode = (mode + 1) % BOOT_COUNT; |
329 | init_mode = BOOT_CANARY; | ||
330 | } | ||
321 | } | 331 | } |
322 | 332 | ||
323 | /* save mode */ | 333 | /* save mode */ |
@@ -642,8 +652,8 @@ int main(int argc, char **argv) | |||
642 | system("/bin/chmod +x /tmp/" BOOTFILE); | 652 | system("/bin/chmod +x /tmp/" BOOTFILE); |
643 | execl("/tmp/" BOOTFILE, BOOTFILE, NULL); | 653 | execl("/tmp/" BOOTFILE, BOOTFILE, NULL); |
644 | printf("execvp failed: %s\n", strerror(errno)); | 654 | printf("execvp failed: %s\n", strerror(errno)); |
645 | /* fallback to OF in case of failure */ | 655 | error_screen("Cannot boot Rockbox!"); |
646 | error_screen("Cannot boot Rockbox"); | 656 | mode = BOOT_TOOLS; |
647 | sleep(2 * HZ); | 657 | sleep(2 * HZ); |
648 | } | 658 | } |
649 | else | 659 | else |