summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/rockbox_flash.c103
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 */
264UINT32 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 */
300unsigned 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);