summaryrefslogtreecommitdiff
path: root/bootloader/rocker_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/rocker_linux.c')
-rw-r--r--bootloader/rocker_linux.c60
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
150static void display_text_center(int y, const char *text) 151static 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 */
168static int get_inactivity_tmo(void) 169static 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' 193static int mounted = 0;
192 * (since the mostly suspends instead of powering down) */
193static 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
204static void mount_storage(int enable) 195static 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' */
210static 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
217static void save_boot_mode(enum boot_mode mode) 222static 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)
227static enum boot_mode get_boot_mode(void) 233static 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