diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-10-16 16:42:37 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-10-16 16:42:37 +0000 |
commit | 546083c78448e7ae526cdf66072bf40a0e4f910a (patch) | |
tree | f307413aff84d9c18bb9495bcb206eb723b4b973 /apps/plugins/rockbox_flash.c | |
parent | 00a228fefbfc9058b89ba914755aa9d5f31da085 (diff) | |
download | rockbox-546083c78448e7ae526cdf66072bf40a0e4f910a.tar.gz rockbox-546083c78448e7ae526cdf66072bf40a0e4f910a.zip |
Merge the necessary changes for the new archos firmware flash images back to the trunk, including the related optimisations.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18821 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/rockbox_flash.c')
-rw-r--r-- | apps/plugins/rockbox_flash.c | 141 |
1 files changed, 32 insertions, 109 deletions
diff --git a/apps/plugins/rockbox_flash.c b/apps/plugins/rockbox_flash.c index d3f0aa4055..6323ca9736 100644 --- a/apps/plugins/rockbox_flash.c +++ b/apps/plugins/rockbox_flash.c | |||
@@ -30,7 +30,7 @@ PLUGIN_HEADER | |||
30 | /* define DUMMY if you only want to "play" with the UI, does no harm */ | 30 | /* define DUMMY if you only want to "play" with the UI, does no harm */ |
31 | /* #define DUMMY */ | 31 | /* #define DUMMY */ |
32 | 32 | ||
33 | #define LATEST_BOOTLOADER_VERSION 1 /* update this with the bootloader */ | 33 | #define LATEST_BOOTLOADER_VERSION 2 /* update this with the bootloader */ |
34 | 34 | ||
35 | #ifndef UINT8 | 35 | #ifndef UINT8 |
36 | #define UINT8 unsigned char | 36 | #define UINT8 unsigned char |
@@ -105,7 +105,8 @@ static UINT8* sector; /* better not place this on the stack... */ | |||
105 | 105 | ||
106 | 106 | ||
107 | /* read the manufacturer and device ID */ | 107 | /* read the manufacturer and device ID */ |
108 | bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID) | 108 | static bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, |
109 | UINT8* pDeviceID) | ||
109 | { | 110 | { |
110 | UINT8 not_manu, not_id; /* read values before switching to ID mode */ | 111 | UINT8 not_manu, not_id; /* read values before switching to ID mode */ |
111 | UINT8 manu, id; /* read values when in ID mode */ | 112 | UINT8 manu, id; /* read values when in ID mode */ |
@@ -141,7 +142,7 @@ bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID) | |||
141 | } | 142 | } |
142 | 143 | ||
143 | /* erase the sector which contains the given address */ | 144 | /* erase the sector which contains the given address */ |
144 | bool EraseSector(volatile UINT8* pAddr) | 145 | static bool EraseSector(volatile UINT8* pAddr) |
145 | { | 146 | { |
146 | #ifdef DUMMY | 147 | #ifdef DUMMY |
147 | (void)pAddr; /* prevents warning */ | 148 | (void)pAddr; /* prevents warning */ |
@@ -168,7 +169,7 @@ bool EraseSector(volatile UINT8* pAddr) | |||
168 | } | 169 | } |
169 | 170 | ||
170 | /* address must be in an erased location */ | 171 | /* address must be in an erased location */ |
171 | inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) | 172 | static inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) |
172 | { | 173 | { |
173 | #ifdef DUMMY | 174 | #ifdef DUMMY |
174 | (void)pAddr; /* prevents warnings */ | 175 | (void)pAddr; /* prevents warnings */ |
@@ -195,7 +196,7 @@ inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) | |||
195 | } | 196 | } |
196 | 197 | ||
197 | /* this returns true if supported and fills the info struct */ | 198 | /* this returns true if supported and fills the info struct */ |
198 | bool GetFlashInfo(tFlashInfo* pInfo) | 199 | static bool GetFlashInfo(tFlashInfo* pInfo) |
199 | { | 200 | { |
200 | rb->memset(pInfo, 0, sizeof(tFlashInfo)); | 201 | rb->memset(pInfo, 0, sizeof(tFlashInfo)); |
201 | 202 | ||
@@ -225,17 +226,8 @@ bool GetFlashInfo(tFlashInfo* pInfo) | |||
225 | 226 | ||
226 | /*********** Tool Functions ************/ | 227 | /*********** Tool Functions ************/ |
227 | 228 | ||
228 | /* place a 32 bit value into memory, big endian */ | ||
229 | void Write32(UINT8* pByte, UINT32 value) | ||
230 | { | ||
231 | pByte[0] = (UINT8)(value >> 24); | ||
232 | pByte[1] = (UINT8)(value >> 16); | ||
233 | pByte[2] = (UINT8)(value >> 8); | ||
234 | pByte[3] = (UINT8)(value); | ||
235 | } | ||
236 | |||
237 | /* read a 32 bit value from memory, big endian */ | 229 | /* read a 32 bit value from memory, big endian */ |
238 | UINT32 Read32(UINT8* pByte) | 230 | static UINT32 Read32(UINT8* pByte) |
239 | { | 231 | { |
240 | UINT32 value; | 232 | UINT32 value; |
241 | 233 | ||
@@ -248,7 +240,7 @@ UINT32 Read32(UINT8* pByte) | |||
248 | } | 240 | } |
249 | 241 | ||
250 | /* get the start address of the second image */ | 242 | /* get the start address of the second image */ |
251 | tImageHeader* GetSecondImage(void) | 243 | static tImageHeader* GetSecondImage(void) |
252 | { | 244 | { |
253 | tImageHeader* pImage1; | 245 | tImageHeader* pImage1; |
254 | UINT32 pos = 0; /* default: not found */ | 246 | UINT32 pos = 0; /* default: not found */ |
@@ -277,88 +269,17 @@ tImageHeader* GetSecondImage(void) | |||
277 | return (tImageHeader*)pos; | 269 | return (tImageHeader*)pos; |
278 | } | 270 | } |
279 | 271 | ||
280 | 272 | /* return bootloader version */ | |
281 | /* Tool function to calculate a CRC32 across some buffer */ | 273 | static inline unsigned BootloaderVersion(void) |
282 | /* third argument is either 0xFFFFFFFF to start or value from last piece */ | ||
283 | UINT32 crc_32(unsigned char* buf, unsigned len, unsigned crc32) | ||
284 | { | ||
285 | /* CCITT standard polynomial 0x04C11DB7 */ | ||
286 | static const UINT32 crc32_lookup[16] = | ||
287 | { /* lookup table for 4 bits at a time is affordable */ | ||
288 | 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, | ||
289 | 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, | ||
290 | 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, | ||
291 | 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD | ||
292 | }; | ||
293 | |||
294 | unsigned char byte; | ||
295 | UINT32 t; | ||
296 | |||
297 | while (len--) | ||
298 | { | ||
299 | byte = *buf++; /* get one byte of data */ | ||
300 | |||
301 | /* upper nibble of our data */ | ||
302 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
303 | t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */ | ||
304 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
305 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
306 | |||
307 | /* lower nibble of our data */ | ||
308 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
309 | t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */ | ||
310 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
311 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
312 | } | ||
313 | |||
314 | return crc32; | ||
315 | } | ||
316 | |||
317 | |||
318 | /* test if the bootloader is up-to-date, returns 0 if yes, else CRC */ | ||
319 | unsigned CheckBootloader(void) | ||
320 | { | 274 | { |
321 | unsigned crc; | 275 | return FB[BOOT_VERS_ADR]; |
322 | UINT32* pFlash = (UINT32*)FB; | ||
323 | int bootloader_version = FB[BOOT_VERS_ADR]; | ||
324 | |||
325 | if (bootloader_version) /* this is a newer image, with a version number */ | ||
326 | { | ||
327 | if (bootloader_version < LATEST_BOOTLOADER_VERSION) | ||
328 | return bootloader_version; | ||
329 | else | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* checksum the bootloader, unfortunately I have no version info yet */ | ||
334 | crc = crc_32((unsigned char*)pFlash[2], pFlash[3], -1); | ||
335 | |||
336 | /* Here I have to check for ARCHOS_* defines in source code, which is | ||
337 | generally strongly discouraged. But here I'm not checking for a certain | ||
338 | feature, I'm checking for the model itself. */ | ||
339 | #if defined(ARCHOS_PLAYER) | ||
340 | if (crc == 0x78DAC94A) | ||
341 | return 0; | ||
342 | #elif defined(ARCHOS_RECORDER) | ||
343 | if (crc == 0xE968702E || crc == 0x7C3D93B4) /* normal or ROMless each */ | ||
344 | return 0; | ||
345 | #elif defined(ARCHOS_RECORDERV2) | ||
346 | if (crc == 0x4511E9B5 || crc == 0x3A93DBDF) | ||
347 | return 0; | ||
348 | #elif defined(ARCHOS_FMRECORDER) | ||
349 | if (crc == 0x4511E9B5 || crc == 0x3A93DBDF) | ||
350 | return 0; | ||
351 | #endif | ||
352 | |||
353 | return crc; | ||
354 | } | 276 | } |
355 | 277 | ||
356 | |||
357 | /*********** Image File Functions ************/ | 278 | /*********** Image File Functions ************/ |
358 | 279 | ||
359 | /* so far, only compressed images in UCL NRV algorithm 2e supported */ | 280 | /* so far, only compressed images in UCL NRV algorithm 2e supported */ |
360 | tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader, | 281 | tCheckResult CheckImageFile(char* filename, int space, |
361 | UINT8* pos) | 282 | tImageHeader* pHeader, UINT8* pos) |
362 | { | 283 | { |
363 | int i; | 284 | int i; |
364 | int fd; | 285 | int fd; |
@@ -487,8 +408,9 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader, | |||
487 | 408 | ||
488 | 409 | ||
489 | /* returns the # of failures, 0 on success */ | 410 | /* returns the # of failures, 0 on success */ |
490 | unsigned ProgramImageFile(char* filename, UINT8* pos, | 411 | static unsigned ProgramImageFile(char* filename, UINT8* pos, |
491 | tImageHeader* pImageHeader, int start, int size) | 412 | tImageHeader* pImageHeader, |
413 | int start, int size) | ||
492 | { | 414 | { |
493 | int i; | 415 | int i; |
494 | int fd; | 416 | int fd; |
@@ -537,8 +459,9 @@ unsigned ProgramImageFile(char* filename, UINT8* pos, | |||
537 | } | 459 | } |
538 | 460 | ||
539 | /* returns the # of failures, 0 on success */ | 461 | /* returns the # of failures, 0 on success */ |
540 | unsigned VerifyImageFile(char* filename, UINT8* pos, | 462 | static unsigned VerifyImageFile(char* filename, UINT8* pos, |
541 | tImageHeader* pImageHeader, int start, int size) | 463 | tImageHeader* pImageHeader, |
464 | int start, int size) | ||
542 | { | 465 | { |
543 | int i; | 466 | int i; |
544 | int fd; | 467 | int fd; |
@@ -586,7 +509,7 @@ unsigned VerifyImageFile(char* filename, UINT8* pos, | |||
586 | 509 | ||
587 | /***************** User Interface Functions *****************/ | 510 | /***************** User Interface Functions *****************/ |
588 | 511 | ||
589 | int WaitForButton(void) | 512 | static int WaitForButton(void) |
590 | { | 513 | { |
591 | int button; | 514 | int button; |
592 | 515 | ||
@@ -598,8 +521,9 @@ int WaitForButton(void) | |||
598 | return button; | 521 | return button; |
599 | } | 522 | } |
600 | 523 | ||
524 | #ifdef HAVE_LCD_BITMAP | ||
601 | /* helper for DoUserDialog() */ | 525 | /* helper for DoUserDialog() */ |
602 | void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | 526 | static void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) |
603 | { | 527 | { |
604 | char buf[32]; | 528 | char buf[32]; |
605 | 529 | ||
@@ -636,9 +560,8 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | |||
636 | 560 | ||
637 | 561 | ||
638 | /* Kind of our main function, defines the application flow. */ | 562 | /* Kind of our main function, defines the application flow. */ |
639 | #ifdef HAVE_LCD_BITMAP | ||
640 | /* recorder version */ | 563 | /* recorder version */ |
641 | void DoUserDialog(char* filename) | 564 | static void DoUserDialog(char* filename) |
642 | { | 565 | { |
643 | tImageHeader ImageHeader; | 566 | tImageHeader ImageHeader; |
644 | tFlashInfo FlashInfo; | 567 | tFlashInfo FlashInfo; |
@@ -648,7 +571,7 @@ void DoUserDialog(char* filename) | |||
648 | UINT32 space, aligned_size, true_size; | 571 | UINT32 space, aligned_size, true_size; |
649 | UINT8* pos; | 572 | UINT8* pos; |
650 | ssize_t memleft; | 573 | ssize_t memleft; |
651 | UINT32 crc; | 574 | unsigned bl_version; |
652 | bool show_greet = false; | 575 | bool show_greet = false; |
653 | 576 | ||
654 | /* this can only work if Rockbox runs in DRAM, not flash ROM */ | 577 | /* this can only work if Rockbox runs in DRAM, not flash ROM */ |
@@ -692,10 +615,10 @@ void DoUserDialog(char* filename) | |||
692 | return; /* exit */ | 615 | return; /* exit */ |
693 | } | 616 | } |
694 | 617 | ||
695 | crc = CheckBootloader(); | 618 | bl_version = BootloaderVersion(); |
696 | if (crc) /* outdated version found */ | 619 | if (bl_version < LATEST_BOOTLOADER_VERSION) |
697 | { | 620 | { |
698 | rb->snprintf(buf, sizeof(buf), "(check=0x%08lx)", crc); | 621 | rb->snprintf(buf, sizeof(buf), "Bootloader V%d", bl_version); |
699 | rb->lcd_puts(0, 0, buf); | 622 | rb->lcd_puts(0, 0, buf); |
700 | rb->lcd_puts(0, 1, "Hint: You're not "); | 623 | rb->lcd_puts(0, 1, "Hint: You're not "); |
701 | rb->lcd_puts(0, 2, "using the latest "); | 624 | rb->lcd_puts(0, 2, "using the latest "); |
@@ -842,7 +765,7 @@ void DoUserDialog(char* filename) | |||
842 | #else /* #ifdef HAVE_LCD_BITMAP */ | 765 | #else /* #ifdef HAVE_LCD_BITMAP */ |
843 | 766 | ||
844 | /* Player version */ | 767 | /* Player version */ |
845 | void DoUserDialog(char* filename) | 768 | static void DoUserDialog(char* filename) |
846 | { | 769 | { |
847 | tImageHeader ImageHeader; | 770 | tImageHeader ImageHeader; |
848 | tFlashInfo FlashInfo; | 771 | tFlashInfo FlashInfo; |
@@ -852,7 +775,7 @@ void DoUserDialog(char* filename) | |||
852 | UINT32 space, aligned_size, true_size; | 775 | UINT32 space, aligned_size, true_size; |
853 | UINT8* pos; | 776 | UINT8* pos; |
854 | ssize_t memleft; | 777 | ssize_t memleft; |
855 | UINT32 crc; | 778 | unsigned bl_version; |
856 | 779 | ||
857 | /* this can only work if Rockbox runs in DRAM, not flash ROM */ | 780 | /* this can only work if Rockbox runs in DRAM, not flash ROM */ |
858 | if ((UINT8*)rb >= FB && (UINT8*)rb < FB + 4096*1024) /* 4 MB max */ | 781 | if ((UINT8*)rb >= FB && (UINT8*)rb < FB + 4096*1024) /* 4 MB max */ |
@@ -890,8 +813,8 @@ void DoUserDialog(char* filename) | |||
890 | return; /* exit */ | 813 | return; /* exit */ |
891 | } | 814 | } |
892 | 815 | ||
893 | crc = CheckBootloader(); | 816 | bl_version = BootloaderVersion(); |
894 | if (crc) /* outdated version found */ | 817 | if (bl_version < LATEST_BOOTLOADER_VERSION) |
895 | { | 818 | { |
896 | rb->lcd_puts_scroll(0, 0, "Hint: You're not using the latest bootloader. A full reflash is recommended, but not required."); | 819 | rb->lcd_puts_scroll(0, 0, "Hint: You're not using the latest bootloader. A full reflash is recommended, but not required."); |
897 | rb->lcd_puts_scroll(0, 1, "Press [Menu] to ignore"); | 820 | rb->lcd_puts_scroll(0, 1, "Press [Menu] to ignore"); |
@@ -939,7 +862,7 @@ void DoUserDialog(char* filename) | |||
939 | rb->lcd_puts_scroll(0, 1, "File invalid. Blocksize too small?"); | 862 | rb->lcd_puts_scroll(0, 1, "File invalid. Blocksize too small?"); |
940 | break; | 863 | break; |
941 | case eBadRomLink: | 864 | case eBadRomLink: |
942 | rb->lcd_puts_scroll(0, 1, "BootBox mismatch"); | 865 | rb->lcd_puts_scroll(0, 1, "RomBox mismatch."); |
943 | break; | 866 | break; |
944 | default: | 867 | default: |
945 | rb->lcd_puts_scroll(0, 1, "Check failed."); | 868 | rb->lcd_puts_scroll(0, 1, "Check failed."); |