1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Dave Chapman
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
33 #include "i2c-s5l8700.h"
40 #include "backlight.h"
41 #include "backlight-target.h"
49 /* Safety measure - maximum allowed firmware image size.
50 The largest known current (October 2009) firmware is about 6.2MB so
53 #define MAX_LOADSIZE (8*1024*1024)
55 /* The buffer to load the firmware into - use an uncached alias of 0x08000000 */
56 unsigned char *loadbuffer
= (unsigned char *)0x48000000;
60 void fatal_error(void)
63 bool holdstatus
=false;
65 /* System font is 6 pixels wide */
66 printf("Hold MENU+SELECT to");
67 printf("reboot then SELECT+PLAY");
68 printf("for disk mode");
72 if (button_hold() != holdstatus
) {
75 lcd_puts(0, line
, "Hold switch on!");
78 lcd_puts(0, line
, " ");
85 /* aes_decrypt() and readfw() functions taken from iLoader.
86 (C) Michael Sparmann and licenced under GPL v2 or later.
89 static void aes_decrypt(void* data
, uint32_t size
)
104 for (ptr
= (size
>> 2) - 4; ; ptr
-= 4)
106 AESOUTADDR
= (uint32_t)data
+ (ptr
<< 2);
107 AESINADDR
= (uint32_t)data
+ (ptr
<< 2);
108 AESAUXADDR
= (uint32_t)data
+ (ptr
<< 2);
112 while ((AESSTATUS
& 6) == 0);
114 for (i
= 0; i
< 4; i
++)
115 ((uint32_t*)data
)[ptr
+ i
] ^= ((uint32_t*)data
)[ptr
+ i
- 4];
121 static int readfw(char* filename
, void* address
, int* size
)
124 uint32_t startsector
= 0;
125 uint32_t buffer
[0x200];
127 if (nand_read_sectors(0, 1, buffer
) != 0)
130 if (*((uint16_t*)((uint32_t)buffer
+ 0x1FE)) != 0xAA55)
133 for (i
= 0x1C2; i
< 0x200; i
+= 0x10) {
134 if (((uint8_t*)buffer
)[i
] == 0) {
135 startsector
= *((uint16_t*)((uint32_t)buffer
+ i
+ 4))
136 | (*((uint16_t*)((uint32_t)buffer
+ i
+ 6)) << 16);
141 if (startsector
== 0)
144 if (nand_read_sectors(startsector
, 1, buffer
) != 0)
147 if (buffer
[0x40] != 0x5B68695D)
150 if (nand_read_sectors(startsector
+ 1 + (buffer
[0x41] >> 11), 1, buffer
) != 0)
153 for (i
= 0; i
< 0x1FE; i
+= 10) {
154 if (memcmp(&buffer
[i
], filename
, 8) == 0) {
155 uint32_t filesector
= startsector
+ 1 + (buffer
[i
+ 3] >> 11);
156 *size
= buffer
[i
+ 4];
158 if (nand_read_sectors(filesector
, ((*size
+ 0x7FF) >> 11), address
) != 0)
176 bool button_was_held
;
178 /* Check the button hold status as soon as possible - to
179 give the user maximum chance to turn it on in order to
180 reset the settings in rockbox. */
181 button_was_held
= button_hold();
190 backlight_init(); /* Turns on the backlight */
195 lcd_set_foreground(LCD_WHITE
);
196 lcd_set_background(LCD_BLACK
);
203 /* Enable bootloader messages */
204 if (btn
==BUTTON_RIGHT
)
207 lcd_setfont(FONT_SYSFIXED
);
209 printf("Rockbox boot loader");
210 printf("Version: " RBVERSION
);
215 printf("ATA error: %d", i
);
220 rc
= disk_mount_all();
223 printf("No partition found");
227 if (button_was_held
|| (btn
==BUTTON_MENU
)) {
228 /* If either the hold switch was on, or the Menu button was held, then
229 try the Apple firmware */
230 printf("Loading original firmware...");
232 if ((rc
= readfw("DNANkbso", loadbuffer
, &size
)) < 0) {
233 printf("readfw error %d",rc
);
237 /* Now we need to decrypt it */
238 printf("Decrypting %d bytes...",size
);
240 aes_decrypt(loadbuffer
, size
);
242 printf("Loading Rockbox...");
243 rc
=load_firmware(loadbuffer
, BOOTFILE
, MAX_LOADSIZE
);
247 printf("Can't load " BOOTFILE
": ");
248 printf(strerror(rc
));
252 printf("Rockbox loaded.");
256 /* If we get here, we have a new firmware image at 0x08000000, run it */
257 printf("Executing...");
261 /* Remap the bootrom back to zero - that's how the NOR bootloader leaves
266 /* Disable caches and protection unit */
268 "mrc 15, 0, r0, c1, c0, 0 \n"
269 "bic r0, r0, #0x1000 \n"
270 "bic r0, r0, #0x5 \n"
271 "mcr 15, 0, r0, c1, c0, 0 \n"
274 /* Branch to start of DRAM */
275 asm volatile("ldr pc, =0x08000000");