diff options
Diffstat (limited to 'bootloader')
-rw-r--r-- | bootloader/x1000/utils.c | 78 | ||||
-rw-r--r-- | bootloader/x1000/x1000bootloader.h | 5 |
2 files changed, 83 insertions, 0 deletions
diff --git a/bootloader/x1000/utils.c b/bootloader/x1000/utils.c index b8f86c3ed1..1b56bdf50a 100644 --- a/bootloader/x1000/utils.c +++ b/bootloader/x1000/utils.c | |||
@@ -172,3 +172,81 @@ int load_uimage_flash(uint32_t addr, uint32_t length, | |||
172 | 172 | ||
173 | return handle; | 173 | return handle; |
174 | } | 174 | } |
175 | |||
176 | int dump_flash(int fd, uint32_t addr, uint32_t length) | ||
177 | { | ||
178 | static char buf[8192]; | ||
179 | int ret = 0; | ||
180 | |||
181 | nand_drv* ndrv = nand_init(); | ||
182 | nand_lock(ndrv); | ||
183 | |||
184 | ret = nand_open(ndrv); | ||
185 | if(ret != NAND_SUCCESS) { | ||
186 | splashf(5*HZ, "NAND open failed\n"); | ||
187 | nand_unlock(ndrv); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | while(length > 0) { | ||
192 | uint32_t count = MIN(length, sizeof(buf)); | ||
193 | ret = nand_read_bytes(ndrv, addr, count, buf); | ||
194 | if(ret != NAND_SUCCESS) { | ||
195 | splashf(5*HZ, "Dump failed\nNAND I/O error"); | ||
196 | goto out; | ||
197 | } | ||
198 | |||
199 | if(write(fd, buf, count) != (ssize_t)count) { | ||
200 | splashf(5*HZ, "Dump failed\nFile I/O error"); | ||
201 | ret = -1; | ||
202 | goto out; | ||
203 | } | ||
204 | |||
205 | length -= count; | ||
206 | addr += count; | ||
207 | } | ||
208 | |||
209 | out: | ||
210 | nand_close(ndrv); | ||
211 | nand_unlock(ndrv); | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | int dump_flash_file(const char* file, uint32_t addr, uint32_t length) | ||
216 | { | ||
217 | if(check_disk(true) != DISK_PRESENT) | ||
218 | return -1; | ||
219 | |||
220 | splashf(0, "Dumping...\n%s\n0x%08lx\n%lu bytes", file, addr, length); | ||
221 | |||
222 | int fd = open(file, O_WRONLY|O_CREAT|O_TRUNC); | ||
223 | if(fd < 0) { | ||
224 | splashf(5*HZ, "Cannot open file\n%s", file); | ||
225 | return -2; | ||
226 | } | ||
227 | |||
228 | int rc = dump_flash(fd, addr, length); | ||
229 | if(rc < 0) { | ||
230 | close(fd); | ||
231 | remove(file); | ||
232 | return -3; | ||
233 | } | ||
234 | |||
235 | splashf(5*HZ, "Dumped\n%s", file); | ||
236 | close(fd); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | void dump_of_player(void) | ||
241 | { | ||
242 | #ifdef OF_PLAYER_ADDR | ||
243 | dump_flash_file("/of_player.img", OF_PLAYER_ADDR, OF_PLAYER_LENGTH); | ||
244 | #endif | ||
245 | } | ||
246 | |||
247 | void dump_of_recovery(void) | ||
248 | { | ||
249 | #ifdef OF_RECOVERY_ADDR | ||
250 | dump_flash_file("/of_recovery.img", OF_RECOVERY_ADDR, OF_RECOVERY_LENGTH); | ||
251 | #endif | ||
252 | } | ||
diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index 0309421ced..a7c9927f1b 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h | |||
@@ -167,6 +167,11 @@ int load_uimage_file(const char* filename, | |||
167 | int load_uimage_flash(uint32_t addr, uint32_t length, | 167 | int load_uimage_flash(uint32_t addr, uint32_t length, |
168 | struct uimage_header* uh, size_t* sizep); | 168 | struct uimage_header* uh, size_t* sizep); |
169 | 169 | ||
170 | int dump_flash(int fd, uint32_t addr, uint32_t length); | ||
171 | int dump_flash_file(const char* file, uint32_t addr, uint32_t length); | ||
172 | void dump_of_player(void); | ||
173 | void dump_of_recovery(void); | ||
174 | |||
170 | void recovery_menu(void) __attribute__((noreturn)); | 175 | void recovery_menu(void) __attribute__((noreturn)); |
171 | 176 | ||
172 | #endif /* __X1000BOOTLOADER_H__ */ | 177 | #endif /* __X1000BOOTLOADER_H__ */ |