Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

x1000: Unified flash bootloader installer

Change-Id: Ib1d41d4e7d663ff8a21eb08108c13568f7408533

+390 -324
+6 -17
bootloader/x1000.c
··· 48 48 #include "loader_strerror.h" 49 49 #include "version.h" 50 50 #include "boot-x1000.h" 51 + #include "installer-x1000.h" 51 52 #include <stddef.h> 52 53 #include <stdbool.h> 53 54 #include <string.h> 54 55 #include <stdio.h> 55 56 #include <stdarg.h> 56 - 57 - #ifdef FIIO_M3K 58 - # include "installer-fiiom3k.h" 59 - #endif 60 57 61 58 #if defined(FIIO_M3K) 62 59 # define BL_RECOVERY BUTTON_VOL_UP ··· 68 65 # define BL_DOWN_NAME "VOL-" 69 66 # define BL_SELECT_NAME "PLAY" 70 67 # define BL_QUIT_NAME "POWER" 68 + # define BOOTBACKUP_FILE "/fiiom3k-boot.bin" 71 69 #else 72 70 # error "Missing keymap!" 73 71 #endif ··· 387 385 while(1); 388 386 } 389 387 390 - /* TODO: clean this up, make the installer generic as well */ 391 388 enum { 392 389 INSTALL, 393 390 BACKUP, 394 391 RESTORE, 395 392 }; 396 393 397 - #ifdef FIIO_M3K 398 394 void bootloader_action(int which) 399 395 { 400 396 if(init_disk() != 0) { ··· 414 410 415 411 int rc; 416 412 switch(which) { 417 - case INSTALL: rc = install_boot("/bootloader.m3k"); break; 418 - case BACKUP: rc = backup_boot("/fiiom3k-boot.bin"); break; 419 - case RESTORE: rc = restore_boot("/fiiom3k-boot.bin"); break; 413 + case INSTALL: rc = install_bootloader("/bootloader." BOOTFILE_EXT); break; 414 + case BACKUP: rc = backup_bootloader(BOOTBACKUP_FILE); break; 415 + case RESTORE: rc = restore_bootloader(BOOTBACKUP_FILE); break; 420 416 default: return; 421 417 } 422 418 423 419 static char buf[64]; 424 - snprintf(buf, sizeof(buf), "Failed! Error: %d", rc); 420 + snprintf(buf, sizeof(buf), "%s (%d)", installer_strerror(rc), rc); 425 421 const char* msg1 = rc == 0 ? "Success" : buf; 426 422 const char* msg2 = "Press " BL_QUIT_NAME " to continue"; 427 423 splash2(0, msg1, msg2); ··· 429 425 button_clear_queue(); 430 426 while(button_get(true) != BL_QUIT); 431 427 } 432 - #else 433 - void bootloader_action(int which) 434 - { 435 - (void)which; 436 - splash(5*HZ, "Not implemented!"); 437 - } 438 - #endif 439 428 440 429 void bootloader_install(void) 441 430 {
+3 -3
firmware/SOURCES
··· 1676 1676 #if (CONFIG_STORAGE & STORAGE_SD) 1677 1677 target/mips/ingenic_x1000/sd-x1000.c 1678 1678 #endif 1679 + #ifdef BOOTLOADER 1680 + target/mips/ingenic_x1000/installer-x1000.c 1679 1681 target/mips/ingenic_x1000/spl-start.S 1680 1682 target/mips/ingenic_x1000/spl-x1000.c 1681 1683 common/ucl_decompress.c 1684 + #endif 1682 1685 #endif /* CONFIG_CPU == X1000 */ 1683 1686 1684 1687 #if defined(ONDA_VX747) || defined(ONDA_VX747P) || defined(ONDA_VX777) ··· 1711 1714 target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c 1712 1715 target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c 1713 1716 target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c 1714 - #ifdef BOOTLOADER 1715 - target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c 1716 - #endif 1717 1717 #endif /* FIIO_M3K */ 1718 1718 1719 1719 #if defined(LYRE_PROTO1)
-253
firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c
··· 1 - /*************************************************************************** 2 - * __________ __ ___. 3 - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 - * \/ \/ \/ \/ \/ 8 - * $Id$ 9 - * 10 - * Copyright (C) 2021 Aidan MacDonald 11 - * 12 - * This program is free software; you can redistribute it and/or 13 - * modify it under the terms of the GNU General Public License 14 - * as published by the Free Software Foundation; either version 2 15 - * of the License, or (at your option) any later version. 16 - * 17 - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 - * KIND, either express or implied. 19 - * 20 - ****************************************************************************/ 21 - 22 - #include "installer-fiiom3k.h" 23 - #include "nand-x1000.h" 24 - #include "system.h" 25 - #include "core_alloc.h" 26 - #include "file.h" 27 - #include "microtar.h" 28 - #include <stdint.h> 29 - #include <string.h> 30 - #include <stdio.h> 31 - 32 - #define IMAGE_SIZE (128 * 1024) 33 - #define TAR_SIZE (256 * 1024) 34 - 35 - static int flash_img_read(uint8_t* buffer) 36 - { 37 - nand_drv* drv = nand_init(); 38 - nand_lock(drv); 39 - 40 - int rc = nand_open(drv); 41 - if(rc < 0) 42 - goto error; 43 - 44 - rc = nand_read_bytes(drv, 0, IMAGE_SIZE, buffer); 45 - if(rc < 0) { 46 - rc = INSTALL_ERR_FLASH(NAND_READ, rc); 47 - goto error; 48 - } 49 - 50 - error: 51 - nand_close(drv); 52 - nand_unlock(drv); 53 - return rc; 54 - } 55 - 56 - static int flash_img_write(const uint8_t* buffer) 57 - { 58 - nand_drv* drv = nand_init(); 59 - nand_lock(drv); 60 - 61 - int rc = nand_open(drv); 62 - if(rc < 0) 63 - goto error; 64 - 65 - rc = nand_write_bytes(drv, 0, IMAGE_SIZE, buffer); 66 - if(rc < 0) { 67 - rc = INSTALL_ERR_FLASH(NAND_WRITE, rc); 68 - goto error; 69 - } 70 - 71 - error: 72 - nand_close(drv); 73 - nand_unlock(drv); 74 - return rc; 75 - } 76 - 77 - static int patch_img(mtar_t* tar, uint8_t* buffer, const char* filename, 78 - size_t patch_offset, size_t patch_size) 79 - { 80 - /* Seek to file */ 81 - mtar_header_t h; 82 - int rc = mtar_find(tar, filename, &h); 83 - if(rc != MTAR_ESUCCESS) { 84 - rc = INSTALL_ERR_MTAR(TAR_FIND, rc); 85 - return rc; 86 - } 87 - 88 - /* We need a normal file */ 89 - if(h.type != 0 && h.type != MTAR_TREG) 90 - return INSTALL_ERR_BAD_FORMAT; 91 - 92 - /* Check size does not exceed patch area */ 93 - if(h.size > patch_size) 94 - return INSTALL_ERR_BAD_FORMAT; 95 - 96 - /* Read data directly into patch area, fill unused bytes with 0xff */ 97 - memset(&buffer[patch_offset], 0xff, patch_size); 98 - rc = mtar_read_data(tar, &buffer[patch_offset], h.size); 99 - if(rc != MTAR_ESUCCESS) { 100 - rc = INSTALL_ERR_MTAR(TAR_READ, rc); 101 - return rc; 102 - } 103 - 104 - return INSTALL_SUCCESS; 105 - } 106 - 107 - int install_boot(const char* srcfile) 108 - { 109 - int rc; 110 - mtar_t* tar = NULL; 111 - int handle = -1; 112 - 113 - /* Allocate enough memory for image and tar state */ 114 - size_t bufsize = IMAGE_SIZE + sizeof(mtar_t) + 2*CACHEALIGN_SIZE; 115 - handle = core_alloc("boot_image", bufsize); 116 - if(handle < 0) { 117 - rc = INSTALL_ERR_OUT_OF_MEMORY; 118 - goto error; 119 - } 120 - 121 - uint8_t* buffer = core_get_data(handle); 122 - 123 - /* Tar state alloc */ 124 - CACHEALIGN_BUFFER(buffer, bufsize); 125 - tar = (mtar_t*)buffer; 126 - memset(tar, 0, sizeof(tar)); 127 - 128 - /* Image buffer alloc */ 129 - buffer += sizeof(mtar_t); 130 - CACHEALIGN_BUFFER(buffer, bufsize); 131 - 132 - /* Read the flash -- we need an existing image to patch */ 133 - rc = flash_img_read(buffer); 134 - if(rc < 0) 135 - goto error; 136 - 137 - /* Open the tarball */ 138 - rc = mtar_open(tar, srcfile, "r"); 139 - if(rc != MTAR_ESUCCESS) { 140 - rc = INSTALL_ERR_MTAR(TAR_OPEN, rc); 141 - goto error; 142 - } 143 - 144 - /* Extract the needed files & patch 'em in */ 145 - rc = patch_img(tar, buffer, "spl.m3k", 0, 12 * 1024); 146 - if(rc < 0) 147 - goto error; 148 - 149 - rc = patch_img(tar, buffer, "bootloader.ucl", 0x6800, 102 * 1024); 150 - if(rc < 0) 151 - goto error; 152 - 153 - /* Flash the new image */ 154 - rc = flash_img_write(buffer); 155 - if(rc < 0) 156 - goto error; 157 - 158 - rc = INSTALL_SUCCESS; 159 - 160 - error: 161 - if(tar && tar->close) 162 - mtar_close(tar); 163 - if(handle >= 0) 164 - core_free(handle); 165 - return rc; 166 - } 167 - 168 - int backup_boot(const char* destfile) 169 - { 170 - int rc; 171 - int handle = -1; 172 - int fd = -1; 173 - size_t bufsize = IMAGE_SIZE + CACHEALIGN_SIZE - 1; 174 - handle = core_alloc("boot_image", bufsize); 175 - if(handle < 0) { 176 - rc = INSTALL_ERR_OUT_OF_MEMORY; 177 - goto error; 178 - } 179 - 180 - uint8_t* buffer = core_get_data(handle); 181 - CACHEALIGN_BUFFER(buffer, bufsize); 182 - 183 - rc = flash_img_read(buffer); 184 - if(rc < 0) 185 - goto error; 186 - 187 - fd = open(destfile, O_CREAT|O_TRUNC|O_WRONLY); 188 - if(fd < 0) { 189 - rc = INSTALL_ERR_FILE_IO; 190 - goto error; 191 - } 192 - 193 - ssize_t cnt = write(fd, buffer, IMAGE_SIZE); 194 - if(cnt != IMAGE_SIZE) { 195 - rc = INSTALL_ERR_FILE_IO; 196 - goto error; 197 - } 198 - 199 - error: 200 - if(fd >= 0) 201 - close(fd); 202 - if(handle >= 0) 203 - core_free(handle); 204 - return rc; 205 - } 206 - 207 - int restore_boot(const char* srcfile) 208 - { 209 - int rc; 210 - int handle = -1; 211 - int fd = -1; 212 - size_t bufsize = IMAGE_SIZE + CACHEALIGN_SIZE - 1; 213 - handle = core_alloc("boot_image", bufsize); 214 - if(handle < 0) { 215 - rc = INSTALL_ERR_OUT_OF_MEMORY; 216 - goto error; 217 - } 218 - 219 - uint8_t* buffer = core_get_data(handle); 220 - CACHEALIGN_BUFFER(buffer, bufsize); 221 - 222 - fd = open(srcfile, O_RDONLY); 223 - if(fd < 0) { 224 - rc = INSTALL_ERR_FILE_NOT_FOUND; 225 - goto error; 226 - } 227 - 228 - off_t fsize = filesize(fd); 229 - if(fsize != IMAGE_SIZE) { 230 - rc = INSTALL_ERR_BAD_FORMAT; 231 - goto error; 232 - } 233 - 234 - ssize_t cnt = read(fd, buffer, IMAGE_SIZE); 235 - if(cnt != IMAGE_SIZE) { 236 - rc = INSTALL_ERR_FILE_IO; 237 - goto error; 238 - } 239 - 240 - close(fd); 241 - fd = -1; 242 - 243 - rc = flash_img_write(buffer); 244 - if(rc < 0) 245 - goto error; 246 - 247 - error: 248 - if(fd >= 0) 249 - close(fd); 250 - if(handle >= 0) 251 - core_free(handle); 252 - return rc; 253 - }
-51
firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.h
··· 1 - /*************************************************************************** 2 - * __________ __ ___. 3 - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 - * \/ \/ \/ \/ \/ 8 - * $Id$ 9 - * 10 - * Copyright (C) 2021 Aidan MacDonald 11 - * 12 - * This program is free software; you can redistribute it and/or 13 - * modify it under the terms of the GNU General Public License 14 - * as published by the Free Software Foundation; either version 2 15 - * of the License, or (at your option) any later version. 16 - * 17 - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 - * KIND, either express or implied. 19 - * 20 - ****************************************************************************/ 21 - 22 - #ifndef __INSTALLER_FIIOM3K_H__ 23 - #define __INSTALLER_FIIOM3K_H__ 24 - 25 - #include <stddef.h> 26 - 27 - #define INSTALL_SUCCESS 0 28 - #define INSTALL_ERR_OUT_OF_MEMORY (-1) 29 - #define INSTALL_ERR_FILE_NOT_FOUND (-2) 30 - #define INSTALL_ERR_FILE_IO (-3) 31 - #define INSTALL_ERR_BAD_FORMAT (-4) 32 - #define INSTALL_ERR_NAND_OPEN (-5) 33 - #define INSTALL_ERR_NAND_IDENTIFY (-6) 34 - #define INSTALL_ERR_NAND_READ (-7) 35 - #define INSTALL_ERR_NAND_ENABLE_WRITES (-8) 36 - #define INSTALL_ERR_NAND_ERASE (-9) 37 - #define INSTALL_ERR_NAND_WRITE (-10) 38 - #define INSTALL_ERR_TAR_OPEN (-11) 39 - #define INSTALL_ERR_TAR_FIND (-12) 40 - #define INSTALL_ERR_TAR_READ (-13) 41 - #define INSTALL_ERR_MTAR(x,y) ((INSTALL_ERR_##x)*100 + (y)) 42 - #define INSTALL_ERR_FLASH(x,y) ((INSTALL_ERR_##x)*100 + (y)) 43 - 44 - /* Install the Rockbox bootloader from a bootloader.m3k image */ 45 - extern int install_boot(const char* srcfile); 46 - 47 - /* Backup or restore the bootloader from a raw NAND image */ 48 - extern int backup_boot(const char* destfile); 49 - extern int restore_boot(const char* srcfile); 50 - 51 - #endif /* __INSTALLER_FIIOM3K_H__ */
+326
firmware/target/mips/ingenic_x1000/installer-x1000.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2021 Aidan MacDonald 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + #include "installer-x1000.h" 23 + #include "nand-x1000.h" 24 + #include "core_alloc.h" 25 + #include "file.h" 26 + #include "microtar.h" 27 + #include <stddef.h> 28 + 29 + struct update_part { 30 + const char* filename; 31 + size_t offset; 32 + size_t length; 33 + }; 34 + 35 + /* Parts of the flash to update. The offset and length are given in bytes, 36 + * offset relative to start of flash. The region's new contents are given 37 + * by the named file inside the update archive. If any file is missing, the 38 + * update will fail. (gracefully! nothing is written unless the package has 39 + * all its components) 40 + * 41 + * If the update file is smaller than the region size, unused space at the 42 + * end of the region is padded with 0xff. 43 + * 44 + * NOTE: The current code assumes all parts are contiguous. The current 45 + * update map fits in one eraseblock, but if it ever needs extending beyond 46 + * that, better implement a bitmap to indicate which blocks need updating 47 + * and which can be skipped. We don't want to erase and reprogram blocks 48 + * for no good reason, it's bad for the flash lifespan. 49 + */ 50 + static const struct update_part updates[] = { 51 + { 52 + .filename = "spl." BOOTFILE_EXT, 53 + .offset = 0, 54 + .length = 12 * 1024, 55 + }, 56 + { 57 + .filename = "bootloader.ucl", 58 + .offset = 0x6800, 59 + .length = 102 * 1024, 60 + }, 61 + }; 62 + 63 + static const int num_updates = sizeof(updates) / sizeof(struct update_part); 64 + 65 + /* calculate the offset and length of the update image; this is constant 66 + * for a given target, based on the update parts and the NAND chip geometry. 67 + */ 68 + static void get_image_loc(nand_drv* ndrv, size_t* offptr, size_t* lenptr) 69 + { 70 + size_t blk_size = ndrv->chip->page_size << ndrv->chip->log2_ppb; 71 + size_t img_off = 0; 72 + size_t img_len = 0; 73 + 74 + /* calculate minimal image needed to contain all update blocks */ 75 + for(int i = 0; i < num_updates; ++i) { 76 + img_len = MAX(img_len, updates[i].offset + updates[i].length); 77 + img_off = MIN(img_off, updates[i].offset); 78 + } 79 + 80 + /* round everything to a multiple of the block size */ 81 + size_t r_off = blk_size * (img_off / blk_size); 82 + size_t r_len = blk_size * ((img_len + img_off - r_off + blk_size - 1) / blk_size); 83 + 84 + *offptr = r_off; 85 + *lenptr = r_len; 86 + } 87 + 88 + /* Read in a single part of the update from the tarball, and patch it 89 + * into the image */ 90 + static int patch_part(mtar_t* tar, const struct update_part* part, 91 + uint8_t* img_buf, size_t img_off) 92 + { 93 + mtar_header_t h; 94 + int rc = mtar_find(tar, part->filename, &h); 95 + if(rc != MTAR_ESUCCESS) 96 + return IERR_BAD_FORMAT; 97 + 98 + if(h.type != 0 && h.type != MTAR_TREG) 99 + return IERR_BAD_FORMAT; 100 + 101 + if(h.size > part->length) 102 + return IERR_BAD_FORMAT; 103 + 104 + /* wipe the patched area, and read in the new data */ 105 + memset(&img_buf[part->offset - img_off], 0xff, part->length); 106 + rc = mtar_read_data(tar, &img_buf[part->offset - img_off], h.size); 107 + if(rc != MTAR_ESUCCESS) 108 + return IERR_FILE_IO; 109 + 110 + return IERR_SUCCESS; 111 + } 112 + 113 + struct updater { 114 + int buf_hnd; /* core_alloc handle for our memory buffer */ 115 + size_t buf_len; /* sizeof the buffer */ 116 + 117 + uint8_t* img_buf; 118 + size_t img_off; /* image address in flash */ 119 + size_t img_len; /* image length in flash = size of the buffer */ 120 + 121 + mtar_t* tar; 122 + nand_drv* ndrv; 123 + }; 124 + 125 + static int updater_init(struct updater* u) 126 + { 127 + int rc; 128 + 129 + /* initialize stuff correctly */ 130 + u->buf_hnd = -1; 131 + u->buf_len = 0; 132 + u->img_buf = NULL; 133 + u->img_off = 0; 134 + u->img_len = 0; 135 + u->tar = NULL; 136 + u->ndrv = NULL; 137 + 138 + /* open NAND */ 139 + u->ndrv = nand_init(); 140 + nand_lock(u->ndrv); 141 + rc = nand_open(u->ndrv); 142 + if(rc != NAND_SUCCESS) { 143 + rc = IERR_NAND_OPEN; 144 + goto error; 145 + } 146 + 147 + get_image_loc(u->ndrv, &u->img_off, &u->img_len); 148 + 149 + /* buf_len is a bit oversized here, but it's not really important */ 150 + u->buf_len = u->img_len + sizeof(mtar_t) + 2*CACHEALIGN_SIZE; 151 + u->buf_hnd = core_alloc("boot_image", u->buf_len); 152 + if(u->buf_hnd < 0) { 153 + rc = IERR_OUT_OF_MEMORY; 154 + goto error; 155 + } 156 + 157 + /* allocate from the buffer */ 158 + uint8_t* buffer = (uint8_t*)core_get_data(u->buf_hnd); 159 + size_t buf_len = u->buf_len; 160 + 161 + CACHEALIGN_BUFFER(buffer, buf_len); 162 + u->img_buf = buffer; 163 + buffer += u->img_len; 164 + buf_len -= u->img_len; 165 + 166 + CACHEALIGN_BUFFER(buffer, buf_len); 167 + u->tar = (mtar_t*)buffer; 168 + memset(u->tar, 0, sizeof(struct mtar_t)); 169 + 170 + rc = IERR_SUCCESS; 171 + 172 + error: 173 + return rc; 174 + } 175 + 176 + static void updater_cleanup(struct updater* u) 177 + { 178 + if(u->tar && u->tar->close) 179 + mtar_close(u->tar); 180 + 181 + if(u->buf_hnd >= 0) 182 + core_free(u->buf_hnd); 183 + 184 + if(u->ndrv) { 185 + nand_close(u->ndrv); 186 + nand_unlock(u->ndrv); 187 + } 188 + } 189 + 190 + int install_bootloader(const char* filename) 191 + { 192 + struct updater u; 193 + int rc = updater_init(&u); 194 + if(rc != IERR_SUCCESS) 195 + goto error; 196 + 197 + /* get the image */ 198 + rc = nand_read_bytes(u.ndrv, u.img_off, u.img_len, u.img_buf); 199 + if(rc != NAND_SUCCESS) { 200 + rc = IERR_NAND_READ; 201 + goto error; 202 + } 203 + 204 + /* get the tarball */ 205 + rc = mtar_open(u.tar, filename, "r"); 206 + if(rc != MTAR_ESUCCESS) { 207 + if(rc == MTAR_EOPENFAIL) 208 + rc = IERR_FILE_NOT_FOUND; 209 + else if(rc == MTAR_EREADFAIL) 210 + rc = IERR_FILE_IO; 211 + else 212 + rc = IERR_BAD_FORMAT; 213 + goto error; 214 + } 215 + 216 + /* patch stuff */ 217 + for(int i = 0; i < num_updates; ++i) { 218 + rc = patch_part(u.tar, &updates[i], u.img_buf, u.img_off); 219 + if(rc != IERR_SUCCESS) 220 + goto error; 221 + } 222 + 223 + /* write back the patched image */ 224 + rc = nand_write_bytes(u.ndrv, u.img_off, u.img_len, u.img_buf); 225 + if(rc != NAND_SUCCESS) { 226 + rc = IERR_NAND_WRITE; 227 + goto error; 228 + } 229 + 230 + rc = IERR_SUCCESS; 231 + 232 + error: 233 + updater_cleanup(&u); 234 + return rc; 235 + } 236 + 237 + int backup_bootloader(const char* filename) 238 + { 239 + int rc, fd = 0; 240 + struct updater u; 241 + 242 + rc = updater_init(&u); 243 + if(rc != IERR_SUCCESS) 244 + goto error; 245 + 246 + /* read image */ 247 + rc = nand_read_bytes(u.ndrv, u.img_off, u.img_len, u.img_buf); 248 + if(rc != NAND_SUCCESS) { 249 + rc = IERR_NAND_READ; 250 + goto error; 251 + } 252 + 253 + /* write to file */ 254 + fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY); 255 + if(fd < 0) { 256 + rc = IERR_FILE_IO; 257 + goto error; 258 + } 259 + 260 + ssize_t cnt = write(fd, u.img_buf, u.img_len); 261 + if(cnt < 0 || (size_t)cnt != u.img_len) { 262 + rc = IERR_FILE_IO; 263 + goto error; 264 + } 265 + 266 + rc = IERR_SUCCESS; 267 + 268 + error: 269 + if(fd >= 0) 270 + close(fd); 271 + updater_cleanup(&u); 272 + return rc; 273 + } 274 + 275 + int restore_bootloader(const char* filename) 276 + { 277 + int rc, fd = 0; 278 + struct updater u; 279 + 280 + rc = updater_init(&u); 281 + if(rc != IERR_SUCCESS) 282 + goto error; 283 + 284 + /* read from file */ 285 + fd = open(filename, O_RDONLY); 286 + if(fd < 0) { 287 + rc = IERR_FILE_NOT_FOUND; 288 + goto error; 289 + } 290 + 291 + ssize_t cnt = read(fd, u.img_buf, u.img_len); 292 + if(cnt < 0 || (size_t)cnt != u.img_len) { 293 + rc = IERR_FILE_IO; 294 + goto error; 295 + } 296 + 297 + /* write image */ 298 + rc = nand_write_bytes(u.ndrv, u.img_off, u.img_len, u.img_buf); 299 + if(rc != NAND_SUCCESS) { 300 + rc = IERR_NAND_WRITE; 301 + goto error; 302 + } 303 + 304 + rc = IERR_SUCCESS; 305 + 306 + error: 307 + if(fd >= 0) 308 + close(fd); 309 + updater_cleanup(&u); 310 + return rc; 311 + } 312 + 313 + const char* installer_strerror(int rc) 314 + { 315 + switch(rc) { 316 + case IERR_SUCCESS: return "Success"; 317 + case IERR_OUT_OF_MEMORY: return "Out of memory"; 318 + case IERR_FILE_NOT_FOUND: return "File not found"; 319 + case IERR_FILE_IO: return "Disk I/O error"; 320 + case IERR_BAD_FORMAT: return "Bad archive"; 321 + case IERR_NAND_OPEN: return "NAND open error"; 322 + case IERR_NAND_READ: return "NAND read error"; 323 + case IERR_NAND_WRITE: return "NAND write error"; 324 + default: return "Unknown error!?"; 325 + } 326 + }
+55
firmware/target/mips/ingenic_x1000/installer-x1000.h
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2021 Aidan MacDonald 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + #ifndef __INSTALLER_X1000_H__ 23 + #define __INSTALLER_X1000_H__ 24 + 25 + /* This API is for the bootloader recovery menu and Rockbox utility to handle 26 + * bootloader installation, backup, and restore. 27 + * 28 + * Currently the installer can only handle NAND flash, although the X1000 can 29 + * boot from NOR flash or SD/MMC. Support for other storage media can be added 30 + * when there is a target that needs it. 31 + * 32 + * Bootloader updates are tarballs, and they can "monkey patch" the flash in 33 + * a customizable way (but fixed at compile time). 34 + * 35 + * Backup and restore simply takes the range of eraseblocks touched by the 36 + * monkey patch and copies them to or from a regular file. 37 + */ 38 + 39 + enum { 40 + IERR_SUCCESS = 0, 41 + IERR_OUT_OF_MEMORY, 42 + IERR_FILE_NOT_FOUND, 43 + IERR_FILE_IO, 44 + IERR_BAD_FORMAT, 45 + IERR_NAND_OPEN, 46 + IERR_NAND_READ, 47 + IERR_NAND_WRITE, 48 + }; 49 + 50 + extern int install_bootloader(const char* filename); 51 + extern int backup_bootloader(const char* filename); 52 + extern int restore_bootloader(const char* filename); 53 + extern const char* installer_strerror(int rc); 54 + 55 + #endif /* __INSTALLER_X1000_H__ */