diff --git a/bootloader/x1000/boot.c b/bootloader/x1000/boot.c index 6719375151..ca69e2e057 100644 --- a/bootloader/x1000/boot.c +++ b/bootloader/x1000/boot.c @@ -24,6 +24,7 @@ #include "system.h" #include "kernel.h" #include "power.h" +#include "linuxboot.h" #include "boot-x1000.h" void boot_rockbox(void) @@ -50,3 +51,47 @@ void reboot(void) system_reboot(); while(1); } + +/* + * WARNING: Original firmware can be finicky. + * Be careful when modifying this code. + */ + +static __attribute__((unused)) +void boot_of_helper(uint32_t addr, uint32_t flash_size, const char* args) +{ + struct uimage_header uh; + size_t img_length; + int handle = load_uimage_flash(addr, flash_size, &uh, &img_length); + if(handle < 0) + return; + + gui_shutdown(); + + x1000_dualboot_load_pdma_fw(); + x1000_dualboot_cleanup(); + x1000_dualboot_init_clocktree(); + x1000_dualboot_init_uart2(); + + x1000_boot_linux(core_get_data(handle), img_length, + (void*)uimage_get_load(&uh), + (void*)uimage_get_ep(&uh), args); +} + +void boot_of_player(void) +{ +#if defined(OF_PLAYER_ADDR) + boot_of_helper(OF_PLAYER_ADDR, OF_PLAYER_LENGTH, OF_PLAYER_ARGS); +#else + splash(HZ, "Not supported"); +#endif +} + +void boot_of_recovery(void) +{ +#if defined(OF_RECOVERY_ADDR) + boot_of_helper(OF_RECOVERY_ADDR, OF_RECOVERY_LENGTH, OF_RECOVERY_ARGS); +#else + splash(HZ, "Not supported"); +#endif +} diff --git a/bootloader/x1000/recovery.c b/bootloader/x1000/recovery.c index 3d6a079af8..ffd6151858 100644 --- a/bootloader/x1000/recovery.c +++ b/bootloader/x1000/recovery.c @@ -39,8 +39,15 @@ struct menuitem { /* Defines the recovery menu contents */ static const struct menuitem recovery_items[] = { + {MENUITEM_HEADING, "Boot select", NULL}, + {MENUITEM_ACTION, "Rockbox", &boot_rockbox}, +#ifdef OF_PLAYER_NAME + {MENUITEM_ACTION, OF_PLAYER_NAME, &boot_of_player}, +#endif +#ifdef OF_RECOVERY_NAME + {MENUITEM_ACTION, OF_RECOVERY_NAME, &boot_of_recovery}, +#endif {MENUITEM_HEADING, "System", NULL}, - {MENUITEM_ACTION, "Start Rockbox", &boot_rockbox}, {MENUITEM_ACTION, "USB mode", &usb_mode}, {MENUITEM_ACTION, "Shutdown", &shutdown}, {MENUITEM_ACTION, "Reboot", &reboot}, diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index 9090523c14..88d4e3585b 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h @@ -41,6 +41,17 @@ struct uimage_header; # define BL_SELECT_NAME "PLAY" # define BL_QUIT_NAME "POWER" # define BOOTBACKUP_FILE "/fiiom3k-boot.bin" +// FIXME: OF kernel hangs on the m3k +//# define OF_PLAYER_NAME "FiiO player" +# define OF_PLAYER_ADDR 0x20000 +# define OF_PLAYER_LENGTH (4 * 1024 * 1024) +# define OF_PLAYER_ARGS OF_RECOVERY_ARGS \ + " init=/linuxrc ubi.mtd=3 root=ubi0:rootfs ubi.mtd=4 rootfstype=ubifs rw loglevel=8" +//# define OF_RECOVERY_NAME "FiiO recovery" +# define OF_RECOVERY_ADDR 0x420000 +# define OF_RECOVERY_LENGTH (5 * 1024 * 1024) +# define OF_RECOVERY_ARGS \ + "mem=64M@0x0 no_console_suspend console=ttyS2,115200n8 lpj=5009408 ip=off" #elif defined(SHANLING_Q1) # define BL_RECOVERY BUTTON_NEXT # define BL_UP BUTTON_PREV @@ -52,6 +63,16 @@ struct uimage_header; # define BL_SELECT_NAME "PLAY" # define BL_QUIT_NAME "POWER" # define BOOTBACKUP_FILE "/shanlingq1-boot.bin" +# define OF_PLAYER_NAME "Shanling player" +# define OF_PLAYER_ADDR 0x140000 +# define OF_PLAYER_LENGTH (8 * 1024 * 1024) +# define OF_PLAYER_ARGS OF_RECOVERY_ARGS \ + " init=/linuxrc ubi.mtd=5 root=ubi0:rootfs ubi.mtd=6 rootfstype=ubifs rw" +# define OF_RECOVERY_NAME "Shanling recovery" +# define OF_RECOVERY_ADDR 0x940000 +# define OF_RECOVERY_LENGTH (10 * 1024 * 1024) +# define OF_RECOVERY_ARGS \ + "mem=64M@0x0 no_console_suspend console=ttyS2,115200n8 lpj=5009408 ip=off" #elif defined(EROS_QN) # define BL_RECOVERY BUTTON_VOL_UP # define BL_UP BUTTON_SCROLL_BACK @@ -118,6 +139,8 @@ void bootloader_restore(void); */ void boot_rockbox(void); +void boot_of_player(void); +void boot_of_recovery(void); void shutdown(void); void reboot(void);