From e6c2f26e8239a1d9e3db75fdb9d0fed05af992fa Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 5 Mar 2022 09:42:25 +0000 Subject: x1000: bootloader: add uImage loaders Adds loaders for uImages on the SD card or on a raw flash partition. These work similarily to load_rockbox() and return a buflib alloc and size. Booting the image is left up to the caller. Change-Id: I0d58e8c6a61d8349bc5223431cdd06dfdf2503fa --- bootloader/x1000/utils.c | 76 ++++++++++++++++++++++++++++++++++++++ bootloader/x1000/x1000bootloader.h | 7 ++++ 2 files changed, 83 insertions(+) (limited to 'bootloader') diff --git a/bootloader/x1000/utils.c b/bootloader/x1000/utils.c index 6cb9bb379a..faeab40739 100644 --- a/bootloader/x1000/utils.c +++ b/bootloader/x1000/utils.c @@ -25,8 +25,11 @@ #include "button.h" #include "kernel.h" #include "usb.h" +#include "file.h" #include "rb-loader.h" #include "loader_strerror.h" +#include "linuxboot.h" +#include "nand-x1000.h" /* Set to true if a SYS_USB_CONNECTED event is seen * Set to false if a SYS_USB_DISCONNECTED event is seen @@ -96,3 +99,76 @@ int load_rockbox(const char* filename, size_t* sizep) return handle; } + +int load_uimage_file(const char* filename, + struct uimage_header* uh, size_t* sizep) +{ + if(check_disk(true) != DISK_PRESENT) + return -1; + + int fd = open(filename, O_RDONLY); + if(fd < 0) { + splash2(5*HZ, "Can't open file", filename); + return -2; + } + + int handle = uimage_load(uh, sizep, uimage_fd_reader, (void*)(intptr_t)fd); + if(handle <= 0) { + splash2(5*HZ, "Cannot load uImage", filename); + return -3; + } + + return handle; +} + +struct nand_reader_data +{ + nand_drv* ndrv; + uint32_t addr; + uint32_t end_addr; +}; + +static ssize_t uimage_nand_reader(void* buf, size_t count, void* rctx) +{ + struct nand_reader_data* d = rctx; + + if(d->addr + count > d->end_addr) + count = d->end_addr - d->addr; + + int ret = nand_read_bytes(d->ndrv, d->addr, count, buf); + if(ret != NAND_SUCCESS) + return -1; + + d->addr += count; + return count; +} + +int load_uimage_flash(uint32_t addr, uint32_t length, + struct uimage_header* uh, size_t* sizep) +{ + int handle = -1; + + struct nand_reader_data n; + n.ndrv = nand_init(); + n.addr = addr; + n.end_addr = addr + length; + + nand_lock(n.ndrv); + if(nand_open(n.ndrv) != NAND_SUCCESS) { + splash(5*HZ, "NAND open failed"); + nand_unlock(n.ndrv); + return -1; + } + + handle = uimage_load(uh, sizep, uimage_nand_reader, &n); + + nand_close(n.ndrv); + nand_unlock(n.ndrv); + + if(handle <= 0) { + splash(5*HZ, "uImage load failed"); + return -2; + } + + return handle; +} diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index 84feded9b3..c5984c9a91 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h @@ -24,8 +24,11 @@ #include "config.h" #include +#include #include +struct uimage_header; + #if defined(FIIO_M3K) # define BL_RECOVERY BUTTON_VOL_UP # define BL_UP BUTTON_VOL_UP @@ -108,6 +111,10 @@ int check_disk(bool wait); void usb_mode(void); int load_rockbox(const char* filename, size_t* sizep); +int load_uimage_file(const char* filename, + struct uimage_header* uh, size_t* sizep); +int load_uimage_flash(uint32_t addr, uint32_t length, + struct uimage_header* uh, size_t* sizep); void recovery_menu(void) __attribute__((noreturn)); -- cgit v1.2.3