/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2009 by Dave Chapman * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include #include #include #include #include "config.h" #include "inttypes.h" #include "cpu.h" #include "system.h" #include "lcd.h" #include "i2c-s5l8700.h" #include "kernel.h" #include "thread.h" #include "storage.h" #include "fat.h" #include "disk.h" #include "font.h" #include "backlight.h" #include "backlight-target.h" #include "button.h" #include "panic.h" #include "power.h" #include "file.h" #include "common.h" /* Safety measure - maximum allowed firmware image size. The largest known current (October 2009) firmware is about 6.2MB so we set this to 8MB. */ #define MAX_LOADSIZE (8*1024*1024) /* The buffer to load the firmware into */ unsigned char *loadbuffer = (unsigned char *)0x08000000; /* Bootloader version */ char version[] = APPSVERSION; extern int line; void fatal_error(void) { extern int line; bool holdstatus=false; /* System font is 6 pixels wide */ printf("Hold MENU+SELECT to"); printf("reboot then SELECT+PLAY"); printf("for disk mode"); lcd_update(); while (1) { if (button_hold() != holdstatus) { if (button_hold()) { holdstatus=true; lcd_puts(0, line, "Hold switch on!"); } else { holdstatus=false; lcd_puts(0, line, " "); } lcd_update(); } } } void main(void) { int i; int btn; int rc; bool button_was_held; /* Check the button hold status as soon as possible - to give the user maximum chance to turn it on in order to reset the settings in rockbox. */ button_was_held = button_hold(); system_init(); kernel_init(); i2c_init(); enable_irq(); backlight_init(); /* Turns on the backlight */ lcd_init(); font_init(); lcd_set_foreground(LCD_WHITE); lcd_set_background(LCD_BLACK); lcd_clear_display(); // button_init(); btn=0; /* TODO */ /* Enable bootloader messages */ if (btn==BUTTON_RIGHT) verbose = true; lcd_setfont(FONT_SYSFIXED); printf("Rockbox boot loader"); printf("Version: %s", version); i = storage_init(); if (i != 0) { printf("ATA error: %d", i); fatal_error(); } disk_init(); rc = disk_mount_all(); if (rc<=0) { printf("No partition found"); fatal_error(); } if (button_was_held || (btn==BUTTON_MENU)) { /* If either the hold switch was on, or the Menu button was held, then try the Apple firmware */ printf("Loading original firmware..."); /* TODO */ fatal_error(); } else { printf("Loading Rockbox..."); rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); if (rc != EOK) { printf("Error!"); printf("Can't load " BOOTFILE ": "); printf(strerror(rc)); fatal_error(); } printf("Rockbox loaded."); } /* If we get here, we have a new firmware image at 0x08000000, run it */ disable_irq(); /* Branch to start of DRAM */ asm volatile("ldr pc, =0x08000000"); }