summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c345
1 files changed, 209 insertions, 136 deletions
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c
index 154785ee0b..10a58ace38 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c
@@ -19,192 +19,265 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "installer.h" 22#include "installer-fiiom3k.h"
23#include "nand-x1000.h" 23#include "nand-x1000.h"
24#include "system.h" 24#include "system.h"
25#include "core_alloc.h" 25#include "core_alloc.h"
26#include "file.h" 26#include "file.h"
27#include "microtar.h"
28#include <stdint.h>
29#include <string.h>
30#include <stdio.h>
27 31
28#define INSTALL_SUCCESS 0 32#define IMAGE_SIZE (128 * 1024)
29#define ERR_FLASH_OPEN_FAILED (-1) 33#define TAR_SIZE (256 * 1024)
30#define ERR_FLASH_ENABLE_WP_FAILED (-2) 34
31#define ERR_FLASH_DISABLE_WP_FAILED (-3) 35static int flash_prepare(void)
32#define ERR_FLASH_ERASE_FAILED (-4)
33#define ERR_FLASH_WRITE_FAILED (-5)
34#define ERR_FLASH_READ_FAILED (-6)
35#define ERR_OUT_OF_MEMORY (-7)
36#define ERR_CANNOT_READ_FILE (-8)
37#define ERR_CANNOT_WRITE_FILE (-9)
38#define ERR_WRONG_SIZE (-10)
39
40#define BOOT_IMAGE_SIZE (128 * 1024)
41
42static int install_from_buffer(const void* buf)
43{ 36{
44 int status = INSTALL_SUCCESS;
45 int mf_id, dev_id; 37 int mf_id, dev_id;
38 int rc;
39
40 rc = nand_open();
41 if(rc < 0)
42 return INSTALL_ERR_FLASH(NAND_OPEN, rc);
46 43
47 if(nand_open()) 44 rc = nand_identify(&mf_id, &dev_id);
48 return ERR_FLASH_OPEN_FAILED; 45 if(rc < 0) {
49 if(nand_identify(&mf_id, &dev_id)) { 46 nand_close();
50 status = ERR_FLASH_OPEN_FAILED; 47 return INSTALL_ERR_FLASH(NAND_IDENTIFY, rc);
51 goto _exit;
52 } 48 }
53 49
54 if(nand_enable_writes(true)) { 50 return INSTALL_SUCCESS;
55 status = ERR_FLASH_DISABLE_WP_FAILED; 51}
56 goto _exit; 52
53static void flash_finish(void)
54{
55 /* Ensure writes are always disabled when we finish.
56 * Errors are safe to ignore here, there's nothing we could do anyway. */
57 nand_enable_writes(false);
58 nand_close();
59}
60
61static int flash_img_read(uint8_t* buffer)
62{
63 int rc = flash_prepare();
64 if(rc < 0)
65 goto error;
66
67 rc = nand_read(0, IMAGE_SIZE, buffer);
68 if(rc < 0) {
69 rc = INSTALL_ERR_FLASH(NAND_READ, rc);
70 goto error;
57 } 71 }
58 72
59 if(nand_erase(0, BOOT_IMAGE_SIZE)) { 73 error:
60 status = ERR_FLASH_ERASE_FAILED; 74 flash_finish();
61 goto _exit; 75 return rc;
76}
77
78static int flash_img_write(const uint8_t* buffer)
79{
80 int rc = flash_prepare();
81 if(rc < 0)
82 goto error;
83
84 rc = nand_enable_writes(true);
85 if(rc < 0) {
86 rc = INSTALL_ERR_FLASH(NAND_ENABLE_WRITES, rc);
87 goto error;
62 } 88 }
63 89
64 if(nand_write(0, BOOT_IMAGE_SIZE, (const uint8_t*)buf)) { 90 rc = nand_erase(0, IMAGE_SIZE);
65 status = ERR_FLASH_WRITE_FAILED; 91 if(rc < 0) {
66 goto _exit; 92 rc = INSTALL_ERR_FLASH(NAND_ERASE, rc);
93 goto error;
67 } 94 }
68 95
69 if(nand_enable_writes(false)) { 96 rc = nand_write(0, IMAGE_SIZE, buffer);
70 status = ERR_FLASH_ENABLE_WP_FAILED; 97 if(rc < 0) {
71 goto _exit; 98 rc = INSTALL_ERR_FLASH(NAND_WRITE, rc);
99 goto error;
72 } 100 }
73 101
74 _exit: 102 error:
75 nand_close(); 103 flash_finish();
76 return status; 104 return rc;
77} 105}
78 106
79static int dump_to_buffer(void* buf) 107static int patch_img(mtar_t* tar, uint8_t* buffer, const char* filename,
108 size_t patch_offset, size_t patch_size)
80{ 109{
81 int status = INSTALL_SUCCESS; 110 /* Seek to file */
82 int mf_id, dev_id; 111 mtar_header_t h;
83 112 int rc = mtar_find(tar, filename, &h);
84 if(nand_open()) 113 if(rc != MTAR_ESUCCESS) {
85 return ERR_FLASH_OPEN_FAILED; 114 rc = INSTALL_ERR_MTAR(TAR_FIND, rc);
86 if(nand_identify(&mf_id, &dev_id)) { 115 return rc;
87 status = ERR_FLASH_OPEN_FAILED;
88 goto _exit;
89 } 116 }
90 117
91 if(nand_read(0, BOOT_IMAGE_SIZE, (uint8_t*)buf)) { 118 /* We need a normal file */
92 status = ERR_FLASH_READ_FAILED; 119 if(h.type != 0 && h.type != MTAR_TREG)
93 goto _exit; 120 return INSTALL_ERR_BAD_FORMAT;
121
122 /* Check size does not exceed patch area */
123 if(h.size > patch_size)
124 return INSTALL_ERR_BAD_FORMAT;
125
126 /* Read data directly into patch area, fill unused bytes with 0xff */
127 memset(&buffer[patch_offset], 0xff, patch_size);
128 rc = mtar_read_data(tar, &buffer[patch_offset], h.size);
129 if(rc != MTAR_ESUCCESS) {
130 rc = INSTALL_ERR_MTAR(TAR_READ, rc);
131 return rc;
94 } 132 }
95 133
96 _exit: 134 return INSTALL_SUCCESS;
97 nand_close();
98 return status;
99} 135}
100 136
101int install_bootloader(const char* path) 137int install_boot(const char* srcfile)
102{ 138{
103 /* Allocate memory to hold image */ 139 int rc;
104 size_t bufsize = BOOT_IMAGE_SIZE + CACHEALIGN_SIZE - 1; 140 mtar_t* tar = NULL;
105 int handle = core_alloc("boot_image", bufsize); 141 int handle = -1;
106 if(handle < 0)
107 return ERR_OUT_OF_MEMORY;
108
109 int status = INSTALL_SUCCESS;
110 void* buffer = core_get_data(handle);
111 CACHEALIGN_BUFFER(buffer, bufsize);
112 142
113 /* Open the boot image */ 143 /* Allocate enough memory for image and tar state */
114 int fd = open(path, O_RDONLY); 144 size_t bufsize = IMAGE_SIZE + sizeof(mtar_t) + 2*CACHEALIGN_SIZE;
115 if(fd < 0) { 145 handle = core_alloc("boot_image", bufsize);
116 status = ERR_CANNOT_READ_FILE; 146 if(handle < 0) {
117 goto _exit; 147 rc = INSTALL_ERR_OUT_OF_MEMORY;
148 goto error;
118 } 149 }
119 150
120 /* Check file size */ 151 uint8_t* buffer = core_get_data(handle);
121 off_t fsize = filesize(fd); 152
122 if(fsize != BOOT_IMAGE_SIZE) { 153 /* Tar state alloc */
123 status = ERR_WRONG_SIZE; 154 CACHEALIGN_BUFFER(buffer, bufsize);
124 goto _exit; 155 tar = (mtar_t*)buffer;
125 } 156 memset(tar, 0, sizeof(tar));
157
158 /* Image buffer alloc */
159 buffer += sizeof(mtar_t);
160 CACHEALIGN_BUFFER(buffer, bufsize);
161
162 /* Read the flash -- we need an existing image to patch */
163 rc = flash_img_read(buffer);
164 if(rc < 0)
165 goto error;
126 166
127 /* Read the file into the buffer */ 167 /* Open the tarball */
128 ssize_t cnt = read(fd, buffer, BOOT_IMAGE_SIZE); 168 rc = mtar_open(tar, srcfile, "r");
129 if(cnt != BOOT_IMAGE_SIZE) { 169 if(rc != MTAR_ESUCCESS) {
130 status = ERR_CANNOT_READ_FILE; 170 rc = INSTALL_ERR_MTAR(TAR_OPEN, rc);
131 goto _exit; 171 goto error;
132 } 172 }
133 173
134 /* Perform the installation */ 174 /* Extract the needed files & patch 'em in */
135 status = install_from_buffer(buffer); 175 rc = patch_img(tar, buffer, "spl.m3k", 0, 12 * 1024);
176 if(rc < 0)
177 goto error;
136 178
137 _exit: 179 rc = patch_img(tar, buffer, "bootloader.ucl", 0x6800, 102 * 1024);
138 if(fd >= 0) 180 if(rc < 0)
139 close(fd); 181 goto error;
140 core_free(handle); 182
141 return status; 183 /* Flash the new image */
184 rc = flash_img_write(buffer);
185 if(rc < 0)
186 goto error;
187
188 rc = INSTALL_SUCCESS;
189
190 error:
191 if(tar && tar->close)
192 mtar_close(tar);
193 if(handle >= 0)
194 core_free(handle);
195 return rc;
142} 196}
143 197
144/* Dump the current bootloader to a file */ 198int backup_boot(const char* destfile)
145int dump_bootloader(const char* path)
146{ 199{
147 /* Allocate memory to hold image */ 200 int rc;
148 size_t bufsize = BOOT_IMAGE_SIZE + CACHEALIGN_SIZE - 1; 201 int handle = -1;
149 int handle = core_alloc("boot_image", bufsize);
150 if(handle < 0)
151 return -1;
152
153 /* Read data from flash */
154 int fd = -1; 202 int fd = -1;
155 void* buffer = core_get_data(handle); 203 size_t bufsize = IMAGE_SIZE + CACHEALIGN_SIZE - 1;
204 handle = core_alloc("boot_image", bufsize);
205 if(handle < 0) {
206 rc = INSTALL_ERR_OUT_OF_MEMORY;
207 goto error;
208 }
209
210 uint8_t* buffer = core_get_data(handle);
156 CACHEALIGN_BUFFER(buffer, bufsize); 211 CACHEALIGN_BUFFER(buffer, bufsize);
157 int status = dump_to_buffer(buffer);
158 if(status)
159 goto _exit;
160 212
161 /* Open file */ 213 rc = flash_img_read(buffer);
162 fd = open(path, O_CREAT|O_TRUNC|O_WRONLY); 214 if(rc < 0)
215 goto error;
216
217 fd = open(destfile, O_CREAT|O_TRUNC|O_WRONLY);
163 if(fd < 0) { 218 if(fd < 0) {
164 status = ERR_CANNOT_WRITE_FILE; 219 rc = INSTALL_ERR_FILE_IO;
165 goto _exit; 220 goto error;
166 } 221 }
167 222
168 /* Write data to file */ 223 ssize_t cnt = write(fd, buffer, IMAGE_SIZE);
169 ssize_t cnt = write(fd, buffer, BOOT_IMAGE_SIZE); 224 if(cnt != IMAGE_SIZE) {
170 if(cnt != BOOT_IMAGE_SIZE) { 225 rc = INSTALL_ERR_FILE_IO;
171 status = ERR_CANNOT_WRITE_FILE; 226 goto error;
172 goto _exit;
173 } 227 }
174 228
175 _exit: 229 error:
176 if(fd >= 0) 230 if(fd >= 0)
177 close(fd); 231 close(fd);
178 core_free(handle); 232 if(handle >= 0)
179 return status; 233 core_free(handle);
234 return rc;
180} 235}
181 236
182const char* installer_strerror(int rc) 237int restore_boot(const char* srcfile)
183{ 238{
184 switch(rc) { 239 int rc;
185 case INSTALL_SUCCESS: 240 int handle = -1;
186 return "Success"; 241 int fd = -1;
187 case ERR_FLASH_OPEN_FAILED: 242 size_t bufsize = IMAGE_SIZE + CACHEALIGN_SIZE - 1;
188 return "Can't open flash device"; 243 handle = core_alloc("boot_image", bufsize);
189 case ERR_FLASH_ENABLE_WP_FAILED: 244 if(handle < 0) {
190 return "Couldn't re-enable write protect"; 245 rc = INSTALL_ERR_OUT_OF_MEMORY;
191 case ERR_FLASH_DISABLE_WP_FAILED: 246 goto error;
192 return "Can't disable write protect";
193 case ERR_FLASH_ERASE_FAILED:
194 return "Flash erase failed";
195 case ERR_FLASH_WRITE_FAILED:
196 return "Flash write error";
197 case ERR_FLASH_READ_FAILED:
198 return "Flash read error";
199 case ERR_OUT_OF_MEMORY:
200 return "Out of memory";
201 case ERR_CANNOT_READ_FILE:
202 return "Error reading file";
203 case ERR_CANNOT_WRITE_FILE:
204 return "Error writing file";
205 case ERR_WRONG_SIZE:
206 return "Wrong file size";
207 default:
208 return "Unknown error";
209 } 247 }
248
249 uint8_t* buffer = core_get_data(handle);
250 CACHEALIGN_BUFFER(buffer, bufsize);
251
252 fd = open(srcfile, O_RDONLY);
253 if(fd < 0) {
254 rc = INSTALL_ERR_FILE_NOT_FOUND;
255 goto error;
256 }
257
258 off_t fsize = filesize(fd);
259 if(fsize != IMAGE_SIZE) {
260 rc = INSTALL_ERR_BAD_FORMAT;
261 goto error;
262 }
263
264 ssize_t cnt = read(fd, buffer, IMAGE_SIZE);
265 if(cnt != IMAGE_SIZE) {
266 rc = INSTALL_ERR_FILE_IO;
267 goto error;
268 }
269
270 close(fd);
271 fd = -1;
272
273 rc = flash_img_write(buffer);
274 if(rc < 0)
275 goto error;
276
277 error:
278 if(fd >= 0)
279 close(fd);
280 if(handle >= 0)
281 core_free(handle);
282 return rc;
210} 283}