echoplayer: load Rockbox from SD card in bootloader
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 603c5bb2bea8988d7245dd1f7518abf483903e4b Author: Aidan MacDonald <[email protected]> Date: Thu Jan 22 15:04:38 2026 +0000 echoplayer: load Rockbox from SD card in bootloader To avoid problems with SDMMC DMA not being able to access all SRAMs equally, the ELF binary is loaded at the top of SDRAM and then copied into place. Change-Id: Icf16d02bc15605539cbe781dd27709225abca8f9 diff --git a/bootloader/echoplayer.c b/bootloader/echoplayer.c index ad83bed339..15e4d743b4 100644 --- a/bootloader/echoplayer.c +++ b/bootloader/echoplayer.c @@ -26,12 +26,21 @@ #include "button.h" #include "storage.h" #include "disk.h" +#include "file.h" #include "file_internal.h" #include "usb.h" +#include "elf.h" +#include "elf_loader.h" #include "rbversion.h" #include "system-echoplayer.h" #include "gpio-stm32h7.h" +#define SDRAM_SIZE (MEMORYSIZE * 1024 * 1024) + +/* Address where Rockbox .elf binary will be cached in RAM */ +#define LOAD_SIZE (2 * 1024 * 1024) +#define LOAD_BUFFER_ADDR (STM32_SDRAM1_BASE + SDRAM_SIZE - LOAD_SIZE) + /* Events for the monitor callback to signal the main thread */ #define EV_POWER_PRESSED MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0) #define EV_POWER_RELEASED MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1) @@ -44,6 +53,29 @@ #define USB_UNPLUGGED_ACTIVE_TIME (30 * HZ) #define USB_UNPLUGGED_INACTIVE_TIME (3 * HZ) +static const struct elf_memory_map rb_elf_mmap[] = { + { + .addr = STM32_ITCM_BASE, + .size = STM32_ITCM_SIZE, + .flags = PF_R | PF_X, + }, + { + .addr = STM32_DTCM_BASE, + .size = STM32_DTCM_SIZE, + .flags = PF_R | PF_W, + }, + { + .addr = STM32_SDRAM1_BASE, + .size = SDRAM_SIZE - LOAD_SIZE, + .flags = PF_R | PF_W | PF_X, + }, +}; + +static const struct elf_load_context rb_elf_ctx = { + .mmap = rb_elf_mmap, + .num_mmap = ARRAYLEN(rb_elf_mmap), +}; + /* Power button monitor state */ static bool pwr_curr_state; static bool pwr_prev_state; @@ -75,6 +107,10 @@ static bool wait_for_power_released; /* Optional error message displayed on LCD */ static const char *status_msg = NULL; +/* Location of Rockbox ELF binary in memory */ +static void *elf_load_addr = NULL; +static size_t elf_load_size = 0; + /* Helper functions */ static bool is_power_button_pressed(void) { @@ -152,6 +188,7 @@ static void go_active(void) gpio_set_level(GPIO_CPU_POWER_ON, 1); storage_enable(true); + disk_mount_all(); } static void go_inactive(void) @@ -213,14 +250,74 @@ static void refresh_display(void) lcd_enable(true); } +static bool load_rockbox(void) +{ + int fd = open(BOOTDIR "/" BOOTFILE, O_RDONLY); + if (fd < 0) + { + status_msg = "Rockbox not found"; + return false; + } + + void *tmp_buf = (void *)LOAD_BUFFER_ADDR; + size_t tmp_size = LOAD_SIZE; + + ssize_t ret = read(fd, tmp_buf, tmp_size); + if (ret < 0) + { + status_msg = "I/O error loading Rockbox"; + goto out; + } + + if ((size_t)ret == tmp_size) + { + status_msg = "Rockbox binary too large"; + goto out; + } + + elf_load_addr = tmp_buf; + elf_load_size = tmp_size; + +out: + close(fd); + return elf_load_addr != NULL; +} + +static void launch_elf(void) +{ + void *entrypoint = NULL; + void (*entry_fn) (void) = NULL; + + if (elf_load_addr == NULL || elf_load_size == 0) + return; + + int err = elf_loadmem(elf_load_addr, elf_load_size, &rb_elf_ctx, &entrypoint); + if (err) + { + status_msg = "Failed to execute Rockbox"; + return; + } + + disk_unmount_all(); + storage_enable(false); + lcd_shutdown(); + + entry_fn = entrypoint; + commit_discard_idcache(); + disable_irq(); + stm32_systick_disable(); + + entry_fn(); +} + static void launch(void) { /* No-op if USB mode was requested */ if (is_usbmode_button_pressed()) return; - /* TODO: load rockbox */ - status_msg = "Can't boot RB yet!"; + load_rockbox(); + launch_elf(); } void main(void) diff --git a/firmware/export/config/echor1.h b/firmware/export/config/echor1.h index 8f11ab8533..3674419c17 100644 --- a/firmware/export/config/echor1.h +++ b/firmware/export/config/echor1.h @@ -124,3 +124,4 @@ #define HAVE_HOTKEY #define AB_REPEAT_ENABLE #define HAVE_BOOTLOADER_SCREENDUMP +#define HAVE_ELF -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs