| Index: libs/boot/export/libboot.h |
| — | — | @@ -28,6 +28,10 @@ |
| 29 | 29 |
|
| 30 | 30 |
|
| 31 | 31 | int verify_rockbox_checksum(void* image, size_t size);
|
| | 32 | +void check_firmware(void** firmware, int* size, bool verify,
|
| | 33 | + void* buf, int maxsize, bool compressed);
|
| | 34 | +void load_from_file(void** firmware, int* size, bool verify, const char* filename, int maxsize);
|
| | 35 | +void load_from_flash(void** firmware, int* size, bool verify, const char* filename, int maxsize);
|
| 32 | 36 |
|
| 33 | 37 |
|
| 34 | 38 | /* emCORE library identifier */
|
| — | — | @@ -49,6 +53,9 @@ |
| 50 | 54 | struct libboot_api
|
| 51 | 55 | {
|
| 52 | 56 | typeof(verify_rockbox_checksum)* verify_rockbox_checksum;
|
| | 57 | + typeof(check_firmware)* check_firmware;
|
| | 58 | + typeof(load_from_file)* load_from_file;
|
| | 59 | + typeof(load_from_flash)* load_from_flash;
|
| 53 | 60 | };
|
| 54 | 61 |
|
| 55 | 62 |
|
| Index: libs/boot/main.c |
| — | — | @@ -27,7 +27,10 @@ |
| 28 | 28 |
|
| 29 | 29 | static struct libboot_api apitable =
|
| 30 | 30 | {
|
| 31 | | - .verify_rockbox_checksum = verify_rockbox_checksum
|
| | 31 | + .verify_rockbox_checksum = verify_rockbox_checksum,
|
| | 32 | + .check_firmware = check_firmware,
|
| | 33 | + .load_from_file = load_from_file,
|
| | 34 | + .load_from_flash = load_from_flash
|
| 32 | 35 | };
|
| 33 | 36 |
|
| 34 | 37 |
|
| — | — | @@ -63,3 +66,70 @@ |
| 64 | 67 | if (checksum) return -1;
|
| 65 | 68 | return 0;
|
| 66 | 69 | }
|
| | 70 | +
|
| | 71 | +void check_firmware(void** firmware, int* size, bool verify,
|
| | 72 | + void* buf, int maxsize, bool compressed)
|
| | 73 | +{
|
| | 74 | + if (compressed && maxsize)
|
| | 75 | + {
|
| | 76 | + void* buf2 = malloc(maxsize);
|
| | 77 | + if (buf2)
|
| | 78 | + {
|
| | 79 | + if (!ucl_decompress(buf, *size, buf2, (uint32_t*)size))
|
| | 80 | + {
|
| | 81 | + free(buf);
|
| | 82 | + buf = realloc(buf2, *size);
|
| | 83 | + if (!buf) buf = buf2;
|
| | 84 | + if (!verify || !verify_rockbox_checksum(buf, *size))
|
| | 85 | + *firmware = buf;
|
| | 86 | + else free(buf);
|
| | 87 | + }
|
| | 88 | + else
|
| | 89 | + {
|
| | 90 | + free(buf2);
|
| | 91 | + free(buf);
|
| | 92 | + }
|
| | 93 | + }
|
| | 94 | + else free(buf);
|
| | 95 | + }
|
| | 96 | + else if (!compressed)
|
| | 97 | + {
|
| | 98 | + if (!verify || !verify_rockbox_checksum(buf, *size)) *firmware = buf;
|
| | 99 | + else free(buf);
|
| | 100 | + }
|
| | 101 | +}
|
| | 102 | +
|
| | 103 | +void load_from_file(void** firmware, int* size, bool verify, const char* filename, int maxsize)
|
| | 104 | +{
|
| | 105 | + int fd = file_open(filename, O_RDONLY);
|
| | 106 | + if (fd > 0)
|
| | 107 | + {
|
| | 108 | + *size = filesize(fd);
|
| | 109 | + if (*size > 0)
|
| | 110 | + {
|
| | 111 | + void* buf = memalign(0x10, *size);
|
| | 112 | + if (buf)
|
| | 113 | + {
|
| | 114 | + if (read(fd, buf, *size) == *size)
|
| | 115 | + check_firmware(firmware, size, verify, buf, maxsize, maxsize);
|
| | 116 | + else free(buf);
|
| | 117 | + }
|
| | 118 | + }
|
| | 119 | + close(fd);
|
| | 120 | + }
|
| | 121 | +}
|
| | 122 | +
|
| | 123 | +void load_from_flash(void** firmware, int* size, bool verify, const char* filename, int maxsize)
|
| | 124 | +{
|
| | 125 | + *size = bootflash_filesize(filename);
|
| | 126 | + if (*size > 0)
|
| | 127 | + {
|
| | 128 | + void* buf = memalign(0x10, *size);
|
| | 129 | + if (buf)
|
| | 130 | + {
|
| | 131 | + bootflash_read(filename, buf, 0, *size);
|
| | 132 | + check_firmware(firmware, size, verify, buf, maxsize,
|
| | 133 | + bootflash_attributes(filename) & 0x800);
|
| | 134 | + }
|
| | 135 | + }
|
| | 136 | +}
|