diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/rockbox_flash.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/apps/plugins/rockbox_flash.c b/apps/plugins/rockbox_flash.c index eb04fbb566..25a97ea25c 100644 --- a/apps/plugins/rockbox_flash.c +++ b/apps/plugins/rockbox_flash.c | |||
@@ -259,6 +259,73 @@ tImageHeader* GetSecondImage(void) | |||
259 | } | 259 | } |
260 | 260 | ||
261 | 261 | ||
262 | /* Tool function to calculate a CRC32 across some buffer */ | ||
263 | /* third argument is either 0xFFFFFFFF to start or value from last piece */ | ||
264 | UINT32 crc_32(unsigned char* buf, unsigned len, unsigned crc32) | ||
265 | { | ||
266 | /* CCITT standard polynomial 0x04C11DB7 */ | ||
267 | static const UINT32 crc32_lookup[16] = | ||
268 | { /* lookup table for 4 bits at a time is affordable */ | ||
269 | 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, | ||
270 | 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, | ||
271 | 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, | ||
272 | 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD | ||
273 | }; | ||
274 | |||
275 | unsigned char byte; | ||
276 | UINT32 t; | ||
277 | |||
278 | while (len--) | ||
279 | { | ||
280 | byte = *buf++; /* get one byte of data */ | ||
281 | |||
282 | /* upper nibble of our data */ | ||
283 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
284 | t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */ | ||
285 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
286 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
287 | |||
288 | /* lower nibble of our data */ | ||
289 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
290 | t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */ | ||
291 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
292 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
293 | } | ||
294 | |||
295 | return crc32; | ||
296 | } | ||
297 | |||
298 | |||
299 | /* test if the bootloader is up-to-date, returns 0 if yes, else CRC */ | ||
300 | unsigned CheckBootloader(void) | ||
301 | { | ||
302 | unsigned crc; | ||
303 | UINT32* pFlash = (UINT32*)FB; | ||
304 | |||
305 | /* checksum the bootloader, unfortunately I have no version info yet */ | ||
306 | crc = crc_32((unsigned char*)pFlash[2], pFlash[3], -1); | ||
307 | |||
308 | /* Here I have to check for ARCHOS_* defines in source code, which is | ||
309 | generally strongly discouraged. But here I'm not checking for a certain | ||
310 | feature, I'm checking for the model itself. */ | ||
311 | #if defined(ARCHOS_PLAYER) | ||
312 | if (crc == 0x78DAC94A) | ||
313 | return 0; | ||
314 | #elif defined(ARCHOS_RECORDER) | ||
315 | if (crc == 0xE968702E || crc == 0x7C3D93B4) /* normal or ROMless each */ | ||
316 | return 0; | ||
317 | #elif defined(ARCHOS_RECORDERV2) | ||
318 | if (crc == 0x4511E9B5 || crc == 0x3A93DBDF) | ||
319 | return 0; | ||
320 | #elif defined(ARCHOS_FMRECORDER) | ||
321 | if (crc == 0x4511E9B5 || crc == 0x3A93DBDF) | ||
322 | return 0; | ||
323 | #endif | ||
324 | |||
325 | return crc; | ||
326 | } | ||
327 | |||
328 | |||
262 | /*********** Image File Functions ************/ | 329 | /*********** Image File Functions ************/ |
263 | 330 | ||
264 | /* so far, only compressed images in UCL NRV algorithm 2e supported */ | 331 | /* so far, only compressed images in UCL NRV algorithm 2e supported */ |
@@ -532,6 +599,7 @@ void DoUserDialog(char* filename, bool show_greet) | |||
532 | UINT32 space, aligned_size, true_size; | 599 | UINT32 space, aligned_size, true_size; |
533 | UINT8* pos; | 600 | UINT8* pos; |
534 | int memleft; | 601 | int memleft; |
602 | UINT32 crc; | ||
535 | 603 | ||
536 | rb->lcd_setfont(FONT_SYSFIXED); | 604 | rb->lcd_setfont(FONT_SYSFIXED); |
537 | 605 | ||
@@ -559,6 +627,27 @@ void DoUserDialog(char* filename, bool show_greet) | |||
559 | rb->splash(HZ*3, true, "No image"); | 627 | rb->splash(HZ*3, true, "No image"); |
560 | return; /* exit */ | 628 | return; /* exit */ |
561 | } | 629 | } |
630 | |||
631 | crc = CheckBootloader(); | ||
632 | if (crc) /* outdated version found */ | ||
633 | { | ||
634 | rb->snprintf(buf, sizeof(buf), " (CRC=0x%08x) ", crc); | ||
635 | rb->lcd_puts(0, 0, buf); | ||
636 | rb->lcd_puts(0, 1, "Hint: You're not "); | ||
637 | rb->lcd_puts(0, 2, "using the latest "); | ||
638 | rb->lcd_puts(0, 3, "bootloader. "); | ||
639 | rb->lcd_puts(0, 4, "A full reflash is "); | ||
640 | rb->lcd_puts(0, 5, "recommended, but "); | ||
641 | rb->lcd_puts(0, 6, "not required. "); | ||
642 | rb->lcd_puts(0, 7, "Press F1 to ignore"); | ||
643 | rb->lcd_update(); | ||
644 | |||
645 | if (WaitForButton() != BUTTON_F1) | ||
646 | { | ||
647 | return; | ||
648 | } | ||
649 | rb->lcd_clear_display(); | ||
650 | } | ||
562 | 651 | ||
563 | if (show_greet) | 652 | if (show_greet) |
564 | { | 653 | { |
@@ -710,6 +799,7 @@ void DoUserDialog(char* filename, bool show_greet) | |||
710 | UINT32 space, aligned_size, true_size; | 799 | UINT32 space, aligned_size, true_size; |
711 | UINT8* pos; | 800 | UINT8* pos; |
712 | int memleft; | 801 | int memleft; |
802 | UINT32 crc; | ||
713 | 803 | ||
714 | /* "allocate" memory */ | 804 | /* "allocate" memory */ |
715 | sector = rb->plugin_get_buffer(&memleft); | 805 | sector = rb->plugin_get_buffer(&memleft); |
@@ -739,6 +829,19 @@ void DoUserDialog(char* filename, bool show_greet) | |||
739 | return; /* exit */ | 829 | return; /* exit */ |
740 | } | 830 | } |
741 | 831 | ||
832 | crc = CheckBootloader(); | ||
833 | if (crc) /* outdated version found */ | ||
834 | { | ||
835 | rb->lcd_puts_scroll(0, 0, "Hint: You're not using the latest bootloader. A full reflash is recommended, but not required."); | ||
836 | rb->lcd_puts_scroll(0, 1, "Press [Menu] to ignore"); | ||
837 | |||
838 | if (WaitForButton() != BUTTON_MENU) | ||
839 | { | ||
840 | return; | ||
841 | } | ||
842 | rb->lcd_clear_display(); | ||
843 | } | ||
844 | |||
742 | if (show_greet) | 845 | if (show_greet) |
743 | { | 846 | { |
744 | rb->snprintf(buf, sizeof(buf), "File: %s", filename); | 847 | rb->snprintf(buf, sizeof(buf), "File: %s", filename); |