From 49fccaf2d925def5cc57fff4a09b98a8fe318cc8 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Tue, 12 May 2009 20:41:44 +0000 Subject: [PATCH] FS#9730 by Torne Wuff - support installing Rockbox in the firmware partition in place of the main Apple firmware. This image is only loaded if no rockbox.ipod is found so does not affect current behaviour. The advantage is a small increase in boottime. This patch also adds documentation to bootloader/ipod.c in the form of a comment describing the booting behaviour. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20921 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/ipod.c | 79 +++++++++++++++++++++++++++++++---- docs/CREDITS | 1 + firmware/target/arm/crt0-pp.S | 7 +++- 3 files changed, 78 insertions(+), 9 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) } +/* The bootloader is started from the OSOS image on the firmware + * partition. There are several ways it can be installed there: + * appended to the Apple firmware, on its own, or appended to + * Rockbox itself. The Apple ROM loader loads the entire OSOS + * image to DRAM_START, whatever it contains. If the bootloader + * is appended to another image then it will've modified the + * entry point in the OSOS header such that the ROM will call the + * bootloader rather than the main image. + * + * So, once the bootloader has control: + * + * 1) If the hold switch is on, or the menu button is being held, + * try to boot the Apple firmware. + * 1a) First, it looks for apple_os.ipod on the FAT32 partition, + * in .rockbox or the root directory. If found it loads that + * without further checking and runs it. + * 1b) Next, it checks to see if the OSOS image already loaded + * into RAM is in fact the Apple firmware with the bootloader + * appended. It looks at DRAM_START+0x20 for the string + * "portalplayer", and if it's there, just jumps back to + * DRAM_START where the entry point was before the bootloader + * was appended. + * 1c) If neither of those worked, it displays an error and dies. + * + * 2) If the play button is being held, try to boot Linux. It looks + * for linux.bin in the root directory, and if it's not there, + * it displays an error and dies. + * + * 3) Otherwise, try to boot Rockbox. + * 3a) First, it looks for rockbox.ipod on the FAT32 partition, + * in .rockbox or the root directory. If found it loads that + * without further checking and runs it. + * 3b) Next, it checks to see if the OSOS image already loaded + * into RAM is in fact Rockbox with the bootloader appended. + * It looks at DRAM_START+0x20 for the string "Rockbox\1" + * (which is inserted there in crt0-pp.S), and if it's there, + * just humps back to DRAM_START where the entry point was + * before the bootloader was appended. + * 3c) If neither of those worked, it displays an error and dies. + * + * The result is that any of the three install configurations work, + * and that images of apple_os.ipod or rockbox.ipod on the FAT32 + * partition take priority over the contents of OSOS (this avoids + * upgrades failing to work if OSOS is not updated). + * + * Loading from OSOS is somewhat faster than loading from FAT32, + * because the Apple ROM doesn't have to deal with filesystems or + * fragmentation, and is already loading from OSOS anyway. Thus, + * the fastest boot configuration that still allows dual booting + * is to install Rockbox into OSOS with the bootloader appended + * (and delete/rename rockbox.ipod from the FAT32 partition). + * + * It is of course faster to just install Rockbox to OSOS alone, + * but then it's impossible to boot the Apple firmware. + */ void* main(void) { @@ -229,7 +284,7 @@ void* main(void) int i; int btn; int rc; - bool haveretailos; + bool haveramos; bool button_was_held; struct partinfo* pinfo; unsigned short* identify_info; @@ -319,8 +374,8 @@ void* main(void) } else if (rc == EFILE_NOT_FOUND) { /* If apple_os.ipod doesn't exist, then check if there is an Apple firmware image in RAM */ - haveretailos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0); - if (haveretailos) { + haveramos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0); + if (haveramos) { /* We have a copy of the retailos in RAM, lets just run it. */ return (void*)DRAM_START; } @@ -346,14 +401,22 @@ void* main(void) } else { printf("Loading Rockbox..."); rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); - if (rc < EOK) { - printf("Error!"); - printf("Can't load " BOOTFILE ": "); - printf(strerror(rc)); - } else { + if (rc == EOK) { printf("Rockbox loaded."); return (void*)DRAM_START; + } else if (rc == EFILE_NOT_FOUND) { + /* if rockbox.ipod doesn't exist, then check if there is a Rockbox + image in RAM */ + haveramos = (memcmp((void*)(DRAM_START+0x20),"Rockbox\1",8)==0); + if (haveramos) { + /* We have a copy of Rockbox in RAM, lets just run it. */ + return (void*)DRAM_START; + } } + + printf("Error!"); + printf("Can't load " BOOTFILE ": "); + printf(strerror(rc)); } /* If we get to here, then we haven't been able to load any firmware */ diff --git a/docs/CREDITS b/docs/CREDITS index c67b349769..e52d5ff58d 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -461,6 +461,7 @@ Kai Posadowsky Jack Halpin Johannes Schwarz Dustin Skoracki +Torne Wuff The libmad team The wavpack team diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S index 210b560560..bd1fc035c9 100644 --- a/firmware/target/arm/crt0-pp.S +++ b/firmware/target/arm/crt0-pp.S @@ -80,7 +80,12 @@ start: msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ b pad_skip -.space 64*4 /* (more than enough) space for exception vectors and mi4 magic */ +.space 6*4 /* pad to offset 0x20 */ + + .ascii "Rockbox" /* signature for bootloader checking osos */ + .byte 1 /* osos boot version, only 1 exists for now */ + +.space 56*4 /* (more than enough) space for exception vectors and mi4 magic */ pad_skip: /* Find out which processor we are - r0 should be preserved for the