summaryrefslogtreecommitdiff
path: root/bootloader/ipod.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/ipod.c')
-rw-r--r--bootloader/ipod.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/bootloader/ipod.c b/bootloader/ipod.c
index d5da776383..e5538b280c 100644
--- a/bootloader/ipod.c
+++ b/bootloader/ipod.c
@@ -222,6 +222,61 @@ void fatal_error(void)
222 222
223} 223}
224 224
225/* The bootloader is started from the OSOS image on the firmware
226 * partition. There are several ways it can be installed there:
227 * appended to the Apple firmware, on its own, or appended to
228 * Rockbox itself. The Apple ROM loader loads the entire OSOS
229 * image to DRAM_START, whatever it contains. If the bootloader
230 * is appended to another image then it will've modified the
231 * entry point in the OSOS header such that the ROM will call the
232 * bootloader rather than the main image.
233 *
234 * So, once the bootloader has control:
235 *
236 * 1) If the hold switch is on, or the menu button is being held,
237 * try to boot the Apple firmware.
238 * 1a) First, it looks for apple_os.ipod on the FAT32 partition,
239 * in .rockbox or the root directory. If found it loads that
240 * without further checking and runs it.
241 * 1b) Next, it checks to see if the OSOS image already loaded
242 * into RAM is in fact the Apple firmware with the bootloader
243 * appended. It looks at DRAM_START+0x20 for the string
244 * "portalplayer", and if it's there, just jumps back to
245 * DRAM_START where the entry point was before the bootloader
246 * was appended.
247 * 1c) If neither of those worked, it displays an error and dies.
248 *
249 * 2) If the play button is being held, try to boot Linux. It looks
250 * for linux.bin in the root directory, and if it's not there,
251 * it displays an error and dies.
252 *
253 * 3) Otherwise, try to boot Rockbox.
254 * 3a) First, it looks for rockbox.ipod on the FAT32 partition,
255 * in .rockbox or the root directory. If found it loads that
256 * without further checking and runs it.
257 * 3b) Next, it checks to see if the OSOS image already loaded
258 * into RAM is in fact Rockbox with the bootloader appended.
259 * It looks at DRAM_START+0x20 for the string "Rockbox\1"
260 * (which is inserted there in crt0-pp.S), and if it's there,
261 * just humps back to DRAM_START where the entry point was
262 * before the bootloader was appended.
263 * 3c) If neither of those worked, it displays an error and dies.
264 *
265 * The result is that any of the three install configurations work,
266 * and that images of apple_os.ipod or rockbox.ipod on the FAT32
267 * partition take priority over the contents of OSOS (this avoids
268 * upgrades failing to work if OSOS is not updated).
269 *
270 * Loading from OSOS is somewhat faster than loading from FAT32,
271 * because the Apple ROM doesn't have to deal with filesystems or
272 * fragmentation, and is already loading from OSOS anyway. Thus,
273 * the fastest boot configuration that still allows dual booting
274 * is to install Rockbox into OSOS with the bootloader appended
275 * (and delete/rename rockbox.ipod from the FAT32 partition).
276 *
277 * It is of course faster to just install Rockbox to OSOS alone,
278 * but then it's impossible to boot the Apple firmware.
279 */
225 280
226void* main(void) 281void* main(void)
227{ 282{
@@ -229,7 +284,7 @@ void* main(void)
229 int i; 284 int i;
230 int btn; 285 int btn;
231 int rc; 286 int rc;
232 bool haveretailos; 287 bool haveramos;
233 bool button_was_held; 288 bool button_was_held;
234 struct partinfo* pinfo; 289 struct partinfo* pinfo;
235 unsigned short* identify_info; 290 unsigned short* identify_info;
@@ -319,8 +374,8 @@ void* main(void)
319 } else if (rc == EFILE_NOT_FOUND) { 374 } else if (rc == EFILE_NOT_FOUND) {
320 /* If apple_os.ipod doesn't exist, then check if there is an Apple 375 /* If apple_os.ipod doesn't exist, then check if there is an Apple
321 firmware image in RAM */ 376 firmware image in RAM */
322 haveretailos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0); 377 haveramos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0);
323 if (haveretailos) { 378 if (haveramos) {
324 /* We have a copy of the retailos in RAM, lets just run it. */ 379 /* We have a copy of the retailos in RAM, lets just run it. */
325 return (void*)DRAM_START; 380 return (void*)DRAM_START;
326 } 381 }
@@ -346,14 +401,22 @@ void* main(void)
346 } else { 401 } else {
347 printf("Loading Rockbox..."); 402 printf("Loading Rockbox...");
348 rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); 403 rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
349 if (rc < EOK) { 404 if (rc == EOK) {
350 printf("Error!");
351 printf("Can't load " BOOTFILE ": ");
352 printf(strerror(rc));
353 } else {
354 printf("Rockbox loaded."); 405 printf("Rockbox loaded.");
355 return (void*)DRAM_START; 406 return (void*)DRAM_START;
407 } else if (rc == EFILE_NOT_FOUND) {
408 /* if rockbox.ipod doesn't exist, then check if there is a Rockbox
409 image in RAM */
410 haveramos = (memcmp((void*)(DRAM_START+0x20),"Rockbox\1",8)==0);
411 if (haveramos) {
412 /* We have a copy of Rockbox in RAM, lets just run it. */
413 return (void*)DRAM_START;
414 }
356 } 415 }
416
417 printf("Error!");
418 printf("Can't load " BOOTFILE ": ");
419 printf(strerror(rc));
357 } 420 }
358 421
359 /* If we get to here, then we haven't been able to load any firmware */ 422 /* If we get to here, then we haven't been able to load any firmware */