diff options
Diffstat (limited to 'bootloader/ipod.c')
-rw-r--r-- | bootloader/ipod.c | 79 |
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 | ||
226 | void* main(void) | 281 | void* 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 */ |