diff options
Diffstat (limited to 'bootloader/rocker_linux.c')
-rw-r--r-- | bootloader/rocker_linux.c | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/bootloader/rocker_linux.c b/bootloader/rocker_linux.c index 4abc88c413..28a1d78487 100644 --- a/bootloader/rocker_linux.c +++ b/bootloader/rocker_linux.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Copyright (C) 2016 by Amaury Pouly | 10 | * Copyright (C) 2016 by Amaury Pouly |
11 | * 2018 by Marcin Bukat | 11 | * 2018 by Marcin Bukat |
12 | * 2018 by Roman Stolyarov | 12 | * 2018 by Roman Stolyarov |
13 | * 2020 by Solomon Peachy | ||
13 | * | 14 | * |
14 | * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing | 15 | * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing |
15 | * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach | 16 | * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach |
@@ -60,6 +61,9 @@ | |||
60 | #define RBFILE "rockbox.x3ii" | 61 | #define RBFILE "rockbox.x3ii" |
61 | #define ICON_NAME bm_hibyicon | 62 | #define ICON_NAME bm_hibyicon |
62 | #define OF_NAME "HIBY PLAYER" | 63 | #define OF_NAME "HIBY PLAYER" |
64 | #define BUTTON_UP BUTTON_OPTION | ||
65 | #define BUTTON_DOWN BUTTON_HOME | ||
66 | #define BUTTON_SELECT BUTTON_PLAY | ||
63 | #include "bitmaps/hibyicon.h" | 67 | #include "bitmaps/hibyicon.h" |
64 | #elif defined(XDUOO_X20) | 68 | #elif defined(XDUOO_X20) |
65 | #define ICON_WIDTH 130 | 69 | #define ICON_WIDTH 130 |
@@ -67,14 +71,30 @@ | |||
67 | #define RBFILE "rockbox.x20" | 71 | #define RBFILE "rockbox.x20" |
68 | #define ICON_NAME bm_hibyicon | 72 | #define ICON_NAME bm_hibyicon |
69 | #define OF_NAME "HIBY PLAYER" | 73 | #define OF_NAME "HIBY PLAYER" |
74 | #define BUTTON_UP BUTTON_OPTION | ||
75 | #define BUTTON_DOWN BUTTON_HOME | ||
76 | #define BUTTON_SELECT BUTTON_PLAY | ||
70 | #include "bitmaps/hibyicon.h" | 77 | #include "bitmaps/hibyicon.h" |
71 | #elif defined(FIIO_M3K) | 78 | #elif defined(FIIO_M3K) |
72 | #define ICON_WIDTH 130 | 79 | #define ICON_WIDTH 130 |
73 | #define ICON_HEIGHT 130 | 80 | #define ICON_HEIGHT 130 |
74 | #define RBFILE "rockbox.fiiom3k" | 81 | #define RBFILE "rockbox.fiiom3k" |
75 | #define ICON_NAME bm_fiioicon | 82 | #define ICON_NAME bm_fiioicon |
83 | #define BUTTON_LEFT BUTTON_PREV | ||
84 | #define BUTTON_RIGHT BUTTON_NEXT | ||
85 | #define BUTTON_SELECT BUTTON_PLAY | ||
76 | #define OF_NAME "FIIO PLAYER" | 86 | #define OF_NAME "FIIO PLAYER" |
77 | #include "bitmaps/fiioicon.h" | 87 | #include "bitmaps/fiioicon.h" |
88 | #elif defined(EROS_Q) | ||
89 | #define ICON_WIDTH 130 | ||
90 | #define ICON_HEIGHT 130 | ||
91 | #define RBFILE "rockbox.erosq" | ||
92 | #define ICON_NAME bm_hibyicon | ||
93 | #define OF_NAME "HIBY PLAYER" | ||
94 | #define BUTTON_UP BUTTON_SCROLL_BACK | ||
95 | #define BUTTON_DOWN BUTTON_SCROLL_FWD | ||
96 | #define BUTTON_SELECT BUTTON_PLAY | ||
97 | #include "bitmaps/hibyicon.h" | ||
78 | #else | 98 | #else |
79 | #error "must define ICON_WIDTH/HEIGHT" | 99 | #error "must define ICON_WIDTH/HEIGHT" |
80 | #endif | 100 | #endif |
@@ -107,21 +127,8 @@ | |||
107 | #error toolsicon has the wrong resolution | 127 | #error toolsicon has the wrong resolution |
108 | #endif | 128 | #endif |
109 | 129 | ||
110 | #ifndef BUTTON_LEFT | 130 | /* If we started ADB, don't immediately boot into USB mode if we plug in. */ |
111 | #define BUTTON_LEFT BUTTON_REW | 131 | static int adb_running = 0; |
112 | #endif | ||
113 | #ifndef BUTTON_RIGHT | ||
114 | #define BUTTON_RIGHT BUTTON_FF | ||
115 | #endif | ||
116 | #ifndef BUTTON_SELECT | ||
117 | #define BUTTON_SELECT BUTTON_PLAY | ||
118 | #endif | ||
119 | #ifndef BUTTON_DOWN | ||
120 | #define BUTTON_DOWN BUTTON_NEXT | ||
121 | #endif | ||
122 | #ifndef BUTTON_UP | ||
123 | #define BUTTON_UP BUTTON_PREV | ||
124 | #endif | ||
125 | 132 | ||
126 | /* return icon y position (x is always centered) */ | 133 | /* return icon y position (x is always centered) */ |
127 | static int get_icon_y(void) | 134 | static int get_icon_y(void) |
@@ -141,7 +148,6 @@ enum boot_mode | |||
141 | BOOT_TOOLS, | 148 | BOOT_TOOLS, |
142 | BOOT_OF, | 149 | BOOT_OF, |
143 | BOOT_COUNT, | 150 | BOOT_COUNT, |
144 | BOOT_USB, /* special */ | ||
145 | BOOT_STOP, /* power down/suspend */ | 151 | BOOT_STOP, /* power down/suspend */ |
146 | }; | 152 | }; |
147 | 153 | ||
@@ -199,6 +205,19 @@ static enum boot_mode load_boot_mode(enum boot_mode mode) | |||
199 | return mode; | 205 | return mode; |
200 | } | 206 | } |
201 | 207 | ||
208 | static void mount_storage(int enable) | ||
209 | { | ||
210 | if (enable) { | ||
211 | system("/bin/mkdir -p " BASE_DIR); | ||
212 | if (system("/bin/mount /dev/mmcblk0 " BASE_DIR)) | ||
213 | system("/bin/mount /dev/mmcblk0p1 " BASE_DIR); | ||
214 | // XXX possibly invoke sys_serv -> "MOUNT:MOUNT:%s %s", blkdev, mntpoint | ||
215 | } else { | ||
216 | system("/bin/unmount " BASE_DIR); | ||
217 | // XXX possibly invoke sys_serv -> "MOUNT:UNMOUNT:%s %s", mntpoint | ||
218 | } | ||
219 | } | ||
220 | |||
202 | static void save_boot_mode(enum boot_mode mode) | 221 | static void save_boot_mode(enum boot_mode mode) |
203 | { | 222 | { |
204 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); | 223 | int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); |
@@ -221,13 +240,12 @@ static enum boot_mode get_boot_mode(void) | |||
221 | #endif | 240 | #endif |
222 | while(true) | 241 | while(true) |
223 | { | 242 | { |
224 | /* on usb detect, return to usb | 243 | /* on usb detect, immediately boot with last choice */ |
225 | * FIXME this is a hack, we need proper usb detection */ | 244 | if(!adb_running && power_input_status() & POWER_INPUT_USB_CHARGER) |
226 | if(power_input_status() & POWER_INPUT_USB_CHARGER) | ||
227 | { | 245 | { |
228 | /* save last choice */ | 246 | /* save last choice */ |
229 | save_boot_mode(mode); | 247 | save_boot_mode(mode); |
230 | return BOOT_USB; | 248 | return mode; |
231 | } | 249 | } |
232 | /* inactivity detection */ | 250 | /* inactivity detection */ |
233 | int timeout = last_activity + get_inactivity_tmo(); | 251 | int timeout = last_activity + get_inactivity_tmo(); |
@@ -318,7 +336,7 @@ void error_screen(const char *msg) | |||
318 | lcd_update(); | 336 | lcd_update(); |
319 | } | 337 | } |
320 | 338 | ||
321 | int choice_screen(const char *title, bool center, int nr_choices, const char *choices[]) | 339 | int choice_screen(const char *title, bool center, int nr_choices, const char *choices[], int nr_extra, const char *extra[]) |
322 | { | 340 | { |
323 | int choice = 0; | 341 | int choice = 0; |
324 | int max_len = 0; | 342 | int max_len = 0; |
@@ -360,6 +378,14 @@ int choice_screen(const char *title, bool center, int nr_choices, const char *ch | |||
360 | line++; | 378 | line++; |
361 | } | 379 | } |
362 | 380 | ||
381 | lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); | ||
382 | line++; | ||
383 | for (int i = 0 ; i < nr_extra && line < nr_lines ; i++) { | ||
384 | sprintf(buf, "%s", extra[i]); | ||
385 | display_text_center(top_y + h * line, buf); | ||
386 | line++; | ||
387 | } | ||
388 | |||
363 | lcd_update(); | 389 | lcd_update(); |
364 | 390 | ||
365 | /* wait for a key */ | 391 | /* wait for a key */ |
@@ -370,15 +396,15 @@ int choice_screen(const char *title, bool center, int nr_choices, const char *ch | |||
370 | if(btn & BUTTON_REPEAT) | 396 | if(btn & BUTTON_REPEAT) |
371 | btn &= ~BUTTON_REPEAT; | 397 | btn &= ~BUTTON_REPEAT; |
372 | /* play -> stop loop and return mode */ | 398 | /* play -> stop loop and return mode */ |
373 | if(btn == BUTTON_SELECT || btn == BUTTON_LEFT) | 399 | if (btn == BUTTON_SELECT) |
374 | { | 400 | { |
375 | free(buf); | 401 | free(buf); |
376 | return btn == BUTTON_SELECT ? choice : -1; | 402 | return btn == BUTTON_SELECT ? choice : -1; |
377 | } | 403 | } |
378 | /* left/right/up/down: change mode */ | 404 | /* left/right/up/down: change mode */ |
379 | if(btn == BUTTON_UP) | 405 | if (btn == BUTTON_UP || btn == BUTTON_LEFT) |
380 | choice = (choice + nr_choices - 1) % nr_choices; | 406 | choice = (choice + nr_choices - 1) % nr_choices; |
381 | if(btn == BUTTON_DOWN) | 407 | if(btn == BUTTON_DOWN || btn == BUTTON_RIGHT) |
382 | choice = (choice + 1) % nr_choices; | 408 | choice = (choice + 1) % nr_choices; |
383 | } | 409 | } |
384 | } | 410 | } |
@@ -437,7 +463,7 @@ void run_script_menu(void) | |||
437 | entries[nr_entries++] = strdup(ent->d_name); | 463 | entries[nr_entries++] = strdup(ent->d_name); |
438 | } | 464 | } |
439 | closedir(dir); | 465 | closedir(dir); |
440 | int idx = choice_screen("RUN SCRIPT", false, nr_entries, entries); | 466 | int idx = choice_screen("RUN SCRIPT", false, nr_entries, entries, 0, NULL); |
441 | if(idx >= 0) | 467 | if(idx >= 0) |
442 | run_file(entries[idx]); | 468 | run_file(entries[idx]); |
443 | for(int i = 0; i < nr_entries; i++) | 469 | for(int i = 0; i < nr_entries; i++) |
@@ -455,6 +481,7 @@ static void adb(int start) | |||
455 | } | 481 | } |
456 | int status; | 482 | int status; |
457 | waitpid(pid, &status, 0); | 483 | waitpid(pid, &status, 0); |
484 | adb_running = start; | ||
458 | #if 0 | 485 | #if 0 |
459 | if(WIFEXITED(status)) | 486 | if(WIFEXITED(status)) |
460 | { | 487 | { |
@@ -471,8 +498,11 @@ static void adb(int start) | |||
471 | 498 | ||
472 | static void tools_screen(void) | 499 | static void tools_screen(void) |
473 | { | 500 | { |
474 | const char *choices[] = {"ADB start", "ADB stop", "Run script", "Restart", "Shutdown"}; | 501 | const char *extra[] = { MODEL_NAME, rbversion }; |
475 | int choice = choice_screen("TOOLS MENU", true, 5, choices); | 502 | printf("Version: %s\n", rbversion); |
503 | printf("%s\n", MODEL_NAME); | ||
504 | const char *choices[] = {"ADB start", "ADB stop", "Run script", "Remount SD", "Restart", "Shutdown", "Recovery", "Back"}; | ||
505 | int choice = choice_screen("TOOLS MENU", true, 8, choices, 2, extra); | ||
476 | if(choice == 0) | 506 | if(choice == 0) |
477 | { | 507 | { |
478 | /* run service menu */ | 508 | /* run service menu */ |
@@ -492,12 +522,30 @@ static void tools_screen(void) | |||
492 | } | 522 | } |
493 | else if(choice == 3) | 523 | else if(choice == 3) |
494 | { | 524 | { |
495 | system_reboot(); | 525 | mount_storage(false); |
526 | mount_storage(true); | ||
496 | } | 527 | } |
497 | else if(choice == 4) | 528 | else if(choice == 4) |
498 | { | 529 | { |
530 | system_reboot(); | ||
531 | } | ||
532 | else if(choice == 5) | ||
533 | { | ||
499 | power_off(); | 534 | power_off(); |
500 | } | 535 | } |
536 | else if(choice == 6) | ||
537 | { | ||
538 | int fd = open("/proc/jz/reset/reset", O_WRONLY); | ||
539 | if (fd >= 0) { | ||
540 | const char *buf = "recovery\n"; | ||
541 | write(fd, buf, strlen(buf)); | ||
542 | close(fd); | ||
543 | } | ||
544 | } | ||
545 | else if (choice == 7) | ||
546 | { | ||
547 | return; | ||
548 | } | ||
501 | } | 549 | } |
502 | 550 | ||
503 | #if 0 | 551 | #if 0 |
@@ -555,11 +603,13 @@ int main(int argc, char **argv) | |||
555 | // if(font_id >= 0) | 603 | // if(font_id >= 0) |
556 | // lcd_setfont(font_id); | 604 | // lcd_setfont(font_id); |
557 | 605 | ||
606 | mount_storage(true); | ||
607 | |||
558 | /* run all tools menu */ | 608 | /* run all tools menu */ |
559 | while(true) | 609 | while(true) |
560 | { | 610 | { |
561 | enum boot_mode mode = get_boot_mode(); | 611 | enum boot_mode mode = get_boot_mode(); |
562 | if(mode == BOOT_USB || mode == BOOT_OF) | 612 | if (mode == BOOT_OF) |
563 | { | 613 | { |
564 | #if 0 | 614 | #if 0 |
565 | fflush(stdout); | 615 | fflush(stdout); |
@@ -567,7 +617,7 @@ int main(int argc, char **argv) | |||
567 | close(fileno(stdout)); | 617 | close(fileno(stdout)); |
568 | close(fileno(stderr)); | 618 | close(fileno(stderr)); |
569 | #endif | 619 | #endif |
570 | /* for now the only way we have to trigger USB mode it to run the OF */ | 620 | mount_storage(false); |
571 | /* boot OF */ | 621 | /* boot OF */ |
572 | execvp("/usr/bin/hiby_player", argv); | 622 | execvp("/usr/bin/hiby_player", argv); |
573 | error_screen("Cannot boot OF"); | 623 | error_screen("Cannot boot OF"); |
@@ -580,12 +630,14 @@ int main(int argc, char **argv) | |||
580 | else if(mode == BOOT_ROCKBOX) | 630 | else if(mode == BOOT_ROCKBOX) |
581 | { | 631 | { |
582 | fflush(stdout); | 632 | fflush(stdout); |
633 | mount_storage(true); | ||
583 | system("/bin/cp " BASE_DIR "/.rockbox/" RBFILE " /tmp"); | 634 | system("/bin/cp " BASE_DIR "/.rockbox/" RBFILE " /tmp"); |
635 | system("/bin/chmod +x /tmp/" RBFILE); | ||
584 | execl("/tmp/" RBFILE, RBFILE, NULL); | 636 | execl("/tmp/" RBFILE, RBFILE, NULL); |
585 | printf("execvp failed: %s\n", strerror(errno)); | 637 | printf("execvp failed: %s\n", strerror(errno)); |
586 | /* fallback to OF in case of failure */ | 638 | /* fallback to OF in case of failure */ |
587 | error_screen("Cannot boot Rockbox"); | 639 | error_screen("Cannot boot Rockbox"); |
588 | sleep(5 * HZ); | 640 | sleep(2 * HZ); |
589 | } | 641 | } |
590 | else | 642 | else |
591 | { | 643 | { |