FS#6554 - Move bootloader code into a common file

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12453 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Linus Nielsen Feltzing 2007-02-22 15:09:49 +00:00
parent 9744433752
commit 46597c9539
5 changed files with 67 additions and 259 deletions

View file

@ -1,10 +1,10 @@
#if defined(IPOD_ARCH)
common.c common.c
#if defined(IPOD_ARCH)
ipod.c ipod.c
#elif defined(GIGABEAT_F) #elif defined(GIGABEAT_F)
gigabeat.c gigabeat.c
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(SANSA_E200) #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(SANSA_E200)
common.c
main-pp.c main-pp.c
#elif defined(ELIO_TPJ1022) #elif defined(ELIO_TPJ1022)
tpj1022.c tpj1022.c

View file

@ -154,7 +154,7 @@ int load_firmware(unsigned char* buf, char* firmware, int buffer_size)
if(sum != chksum) if(sum != chksum)
return EBAD_CHKSUM; return EBAD_CHKSUM;
return len; return EOK;
} }
/* Load raw binary image. */ /* Load raw binary image. */

View file

@ -18,11 +18,10 @@
#include "power.h" #include "power.h"
#include "file.h" #include "file.h"
#include "button-target.h" #include "button-target.h"
#include "common.h"
extern void map_memory(void); extern void map_memory(void);
int line = 0;
char version[] = APPSVERSION; char version[] = APPSVERSION;
static void go_usb_mode(void) static void go_usb_mode(void)
@ -55,30 +54,25 @@ int restore_fwimg01dat(void)
int orig_file = 0, dest_file = 0; int orig_file = 0, dest_file = 0;
int size = 0, size_read; int size = 0, size_read;
static char buf[4096]; static char buf[4096];
char lcd_buf[64];
orig_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG", O_RDONLY); orig_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG", O_RDONLY);
if(orig_file < 0) { if(orig_file < 0) {
/* Couldn't open source file */ /* Couldn't open source file */
lcd_puts(0, line++, "Couldn't open FWIMG01.DAT.ORIG for reading"); printf("Couldn't open FWIMG01.DAT.ORIG for reading");
lcd_update();
return(1); return(1);
} }
lcd_puts(0, line++, "FWIMG01.DAT.ORIG opened for reading"); printf("FWIMG01.DAT.ORIG opened for reading");
lcd_update();
dest_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT", O_RDWR); dest_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT", O_RDWR);
if(dest_file < 0) { if(dest_file < 0) {
/* Couldn't open destination file */ /* Couldn't open destination file */
lcd_puts(0, line++, "Couldn't open FWIMG01.DAT.ORIG for writing"); printf("Couldn't open FWIMG01.DAT.ORIG for writing");
lcd_update();
close(orig_file); close(orig_file);
return(2); return(2);
} }
lcd_puts(0, line++, "FWIMG01.DAT opened for writing"); printf("FWIMG01.DAT opened for writing");
lcd_update();
do { do {
/* Copy in chunks */ /* Copy in chunks */
@ -95,65 +89,22 @@ int restore_fwimg01dat(void)
close(orig_file); close(orig_file);
close(dest_file); close(dest_file);
snprintf(lcd_buf, sizeof(lcd_buf), "Finished copying %ld bytes from", size); printf("Finished copying %ld bytes from", size);
lcd_puts(0, line++, lcd_buf); printf("FWIMG01.DAT.ORIG to FWIMG01.DAT");
lcd_puts(0, line++, "FWIMG01.DAT.ORIG to FWIMG01.DAT");
return(0); return(0);
} }
int load_rockbox(const char* file_name, unsigned char* buf, int buffer_size)
{
int fd;
int rc;
int len;
char str[256];
fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
if(fd < 0) {
fd = open("/" BOOTFILE, O_RDONLY);
if(fd < 0)
return -1;
}
fd = open(file_name, O_RDONLY);
if(fd < 0)
return -2;
len = filesize(fd);
if(len > buffer_size) {
snprintf(str, sizeof(str), "len: %d buf: %d", len, buffer_size);
lcd_puts(0, line++, str);
lcd_update();
return -6;
}
rc = read(fd, buf, len);
if(rc < len) {
snprintf(str, sizeof(str), "len: %d rc: %d", len, rc);
lcd_puts(0, line++, str);
lcd_update();
return -4;
}
close(fd);
return len;
}
char buf[256]; char buf[256];
void display_instructions(void) void display_instructions(void)
{ {
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
lcd_puts(0, line++, "Hold MENU when booting for rescue mode."); printf("Hold MENU when booting for rescue mode.");
lcd_puts(0, line++, " \"VOL+\" button to restore original kernel"); printf(" \"VOL+\" button to restore original kernel");
lcd_puts(0, line++, " \"A\" button to load original firmware"); printf(" \"A\" button to load original firmware");
line++; printf("");
snprintf(buf, sizeof(buf), "FRAME %x TTB %x", FRAME, TTB_BASE); printf("FRAME %x TTB %x", FRAME, TTB_BASE);
lcd_puts(0, line++, buf);
lcd_update();
} }
void * main(void) void * main(void)
@ -179,23 +130,20 @@ void * main(void)
} }
if(GPGDAT & 2) { if(GPGDAT & 2) {
lcd_init(); lcd_init();
lcd_puts(0, line++, "Entering rescue mode.."); printf("Entering rescue mode..");
lcd_update();
go_usb_mode(); go_usb_mode();
while(1); while(1);
} }
if(GPGDAT & 0x10) { if(GPGDAT & 0x10) {
lcd_init(); lcd_init();
load_original = true; load_original = true;
lcd_puts(0, line++, "Loading original firmware..."); printf("Loading original firmware...");
lcd_update();
} }
i = ata_init(); i = ata_init();
i = disk_mount_all(); i = disk_mount_all();
if(!show_bootsplash) { if(!show_bootsplash) {
snprintf(buf, sizeof(buf), "disk_mount_all: %d", i); printf("disk_mount_all: %d", i);
lcd_puts(0, line++, buf);
} }
if(show_bootsplash) { if(show_bootsplash) {
int fd = open("/bootsplash.raw", O_RDONLY); int fd = open("/bootsplash.raw", O_RDONLY);
@ -216,17 +164,15 @@ void * main(void)
if(GPGDAT & 4) { if(GPGDAT & 4) {
/* Try to restore the original kernel/bootloader if a copy is found */ /* Try to restore the original kernel/bootloader if a copy is found */
lcd_puts(0, line++, "Restoring FWIMG01.DAT..."); printf("Restoring FWIMG01.DAT...");
lcd_update();
if(!restore_fwimg01dat()) { if(!restore_fwimg01dat()) {
lcd_puts(0, line++, "Restoring FWIMG01.DAT successful."); printf("Restoring FWIMG01.DAT successful.");
} else { } else {
lcd_puts(0, line++, "Restoring FWIMG01.DAT failed."); printf("Restoring FWIMG01.DAT failed.");
} }
lcd_puts(0, line++, "Now power cycle to boot original"); printf("Now power cycle to boot original");
lcd_update();
while(1); while(1);
} }
@ -242,76 +188,66 @@ void * main(void)
for(i=39; i && buf[i]==' '; i--) for(i=39; i && buf[i]==' '; i--)
buf[i] = 0; buf[i] = 0;
lcd_puts(0, line++, "Model"); printf("Model");
lcd_puts(0, line++, buf); printf(buf);
for(i=0; i < 4; i++) for(i=0; i < 4; i++)
((unsigned short*)buf)[i]=htobe16(identify_info[i+23]); ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
buf[8]=0; buf[8]=0;
lcd_puts(0, line++, "Firmware"); printf("Firmware");
lcd_puts(0, line++, buf); printf(buf);
pinfo = disk_partinfo(0); pinfo = disk_partinfo(0);
snprintf(buf, sizeof(buf), "Partition 0: 0x%02x %ld MB", printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048);
pinfo->type, pinfo->size / 2048);
lcd_puts(0, line++, buf);
lcd_update();
} }
/* Load original firmware */ /* Load original firmware */
if(load_original) { if(load_original) {
loadbuffer = (unsigned char*)0x30008000; loadbuffer = (unsigned char*)0x30008000;
buffer_size =(unsigned char*)0x31000000 - loadbuffer; buffer_size =(unsigned char*)0x31000000 - loadbuffer;
rc = load_rockbox("/rockbox.gigabeat", loadbuffer, buffer_size); rc = load_firmware("rockbox.gigabeat", loadbuffer, buffer_size);
if(rc < 0) { if(rc < EOK) {
lcd_puts(0, line++, "failed to load original firmware. Loading rockbox"); printf("Error!");
lcd_update(); printf("Failed to load original firmware:");
printf(strerror(rc));
printf("Loading rockbox");
sleep(2*HZ); sleep(2*HZ);
goto load_rockbox; goto load_rockbox;
} }
snprintf(buf, sizeof(buf), "Loaded: %d", rc); printf("Loaded: %d", rc);
lcd_puts(0, line++, buf);
lcd_update();
sleep(2*HZ); sleep(2*HZ);
(*((int*)0x7000000)) = 333; (*((int*)0x7000000)) = 333;
rc = *((int*)0x7000000+0x8000000); rc = *((int*)0x7000000+0x8000000);
snprintf(buf, sizeof(buf), "Bank0 mem test: %d", rc); printf("Bank0 mem test: %d", rc);
lcd_puts(0, line++, buf);
lcd_update();
sleep(3*HZ); sleep(3*HZ);
lcd_puts(0, line++, "Woops, should not return from firmware!"); printf("Woops, should not return from firmware!");
lcd_update();
goto usb; goto usb;
} }
load_rockbox: load_rockbox:
map_memory(); map_memory();
if(!show_bootsplash) { if(!show_bootsplash) {
lcd_puts(0, line, "Loading Rockbox..."); printf("Loading Rockbox...");
lcd_update();
} }
loadbuffer = (unsigned char*) 0x100; loadbuffer = (unsigned char*) 0x100;
buffer_size = (unsigned char*)0x400000 - loadbuffer; buffer_size = (unsigned char*)0x400000 - loadbuffer;
rc=load_rockbox("/rockbox.gigabeat", loadbuffer, buffer_size); rc=load_firmware("rockbox.gigabeat", loadbuffer, buffer_size);
if(rc < 0) { if(rc < EOK) {
snprintf(buf, sizeof(buf), "Rockbox error: %d",rc); printf("Error!");
lcd_puts(0, line++, buf); printf("Can't load rockbox.gigabeat:");
lcd_update(); printf(strerror(rc));
} else { } else {
if(!show_bootsplash) { if(!show_bootsplash) {
lcd_puts(0, line++, "Rockbox loaded."); printf("Rockbox loaded.");
lcd_update();
} }
kernel_entry = (void*) loadbuffer; kernel_entry = (void*) loadbuffer;
rc = kernel_entry(); rc = kernel_entry();
snprintf(buf, sizeof(buf), "Woops, should not return from firmware: %d", rc); printf("Woops, should not return from firmware: %d", rc);
lcd_puts(0, line++, buf);
lcd_update();
goto usb; goto usb;
} }
usb: usb:

View file

@ -43,20 +43,19 @@
#include "eeprom_settings.h" #include "eeprom_settings.h"
#include "pcf50606.h" #include "pcf50606.h"
#include "common.h"
#include <stdarg.h> #include <stdarg.h>
/* Maximum allowed firmware image size. 10MB is more than enough */
#define MAX_LOADSIZE (10*1024*1024)
#define DRAM_START 0x31000000 #define DRAM_START 0x31000000
#ifdef HAVE_EEPROM_SETTINGS #ifdef HAVE_EEPROM_SETTINGS
static bool recovery_mode = false; static bool recovery_mode = false;
#endif #endif
int line = 0;
#ifdef HAVE_REMOTE_LCD
int remote_line = 0;
#endif
int usb_screen(void) int usb_screen(void)
{ {
return 0; return 0;
@ -64,41 +63,6 @@ int usb_screen(void)
char version[] = APPSVERSION; char version[] = APPSVERSION;
char printfbuf[256];
void reset_screen(void)
{
lcd_clear_display();
line = 0;
#ifdef HAVE_REMOTE_LCD
lcd_remote_clear_display();
remote_line = 0;
#endif
}
void printf(const char *format, ...)
{
int len;
unsigned char *ptr;
va_list ap;
va_start(ap, format);
ptr = printfbuf;
len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
va_end(ap);
lcd_puts(0, line++, ptr);
lcd_update();
if(line >= 16)
line = 0;
#ifdef HAVE_REMOTE_LCD
lcd_remote_puts(0, remote_line++, ptr);
lcd_remote_update();
if(remote_line >= 8)
remote_line = 0;
#endif
}
/* Reset the cookie for the crt0 crash check */ /* Reset the cookie for the crt0 crash check */
inline void __reset_cookie(void) inline void __reset_cookie(void)
{ {
@ -116,68 +80,6 @@ void start_iriver_fw(void)
asm(" jmp (%a0)"); asm(" jmp (%a0)");
} }
int load_firmware(void)
{
int fd;
int rc;
int len;
unsigned long chksum;
char model[5];
unsigned long sum;
int i;
unsigned char *buf = (unsigned char *)DRAM_START;
fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
if(fd < 0)
{
fd = open("/" BOOTFILE, O_RDONLY);
if(fd < 0)
return -1;
}
len = filesize(fd) - 8;
printf("Length: %x", len);
lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
rc = read(fd, &chksum, 4);
if(rc < 4)
return -2;
printf("Checksum: %x", chksum);
rc = read(fd, model, 4);
if(rc < 4)
return -3;
model[4] = 0;
printf("Model name: %s", model);
lcd_update();
lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
rc = read(fd, buf, len);
if(rc < len)
return -4;
close(fd);
sum = MODEL_NUMBER;
for(i = 0;i < len;i++) {
sum += buf[i];
}
printf("Sum: %x", sum);
if(sum != chksum)
return -5;
return 0;
}
void start_firmware(void) void start_firmware(void)
{ {
asm(" move.w #0x2700,%sr"); asm(" move.w #0x2700,%sr");
@ -353,6 +255,7 @@ void failsafe_menu(void)
int defopt = -1; int defopt = -1;
char buf[32]; char buf[32];
int i; int i;
extern int line;
reset_screen(); reset_screen();
printf("Bootloader %s", version); printf("Bootloader %s", version);
@ -516,15 +419,21 @@ void main(void)
} }
printf("Loading firmware"); printf("Loading firmware");
i = load_firmware(); i = load_firmware((unsigned char *)DRAM_START, BOOTFILE, MAX_LOADSIZE);
printf("Result: %d", i); printf("Result: %s", strerror(i));
if(i == 0)
start_firmware();
if (i < EOK) {
printf("Error!");
printf("Can't load rockbox.ipod:");
printf(strerror(rc));
sleep(HZ*3);
power_off(); power_off();
} else {
start_firmware();
}
#else #else
extern int line;
/* We want to read the buttons as early as possible, before the user /* We want to read the buttons as early as possible, before the user
releases the ON button */ releases the ON button */
@ -721,15 +630,16 @@ void main(void)
} }
printf("Loading firmware"); printf("Loading firmware");
i = load_firmware(); i = load_firmware((unsigned char *)DRAM_START, BOOTFILE, MAX_LOADSIZE);
printf("Result: %d", i); printf("Result: %d", strerror(i));
if (i == 0) if (i == EOK)
start_firmware(); start_firmware();
if (!detect_original_firmware()) if (!detect_original_firmware())
{ {
printf("No firmware found on disk"); printf("No firmware found on disk");
sleep(HZ*2);
shutdown(); shutdown();
} }
else else
@ -739,24 +649,6 @@ void main(void)
/* These functions are present in the firmware library, but we reimplement /* These functions are present in the firmware library, but we reimplement
them here because the originals do a lot more than we want */ them here because the originals do a lot more than we want */
void reset_poweroff_timer(void)
{
}
void screen_dump(void) void screen_dump(void)
{ {
} }
int dbg_ports(void)
{
return 0;
}
void mpeg_stop(void)
{
}
void sys_poweroff(void)
{
}

View file

@ -37,11 +37,10 @@
#include "panic.h" #include "panic.h"
#include "power.h" #include "power.h"
#include "file.h" #include "file.h"
#include "common.h"
char version[] = APPSVERSION; char version[] = APPSVERSION;
int line=0;
void* main(void) void* main(void)
{ {
int i; int i;
@ -54,8 +53,7 @@ void* main(void)
lcd_init(); lcd_init();
font_init(); font_init();
lcd_puts(0, line++ ,"Hello World!"); printf("Hello World!");
lcd_update();
#endif #endif
i=ata_init(); i=ata_init();
@ -108,20 +106,6 @@ void* main(void)
/* These functions are present in the firmware library, but we reimplement /* These functions are present in the firmware library, but we reimplement
them here because the originals do a lot more than we want */ them here because the originals do a lot more than we want */
void reset_poweroff_timer(void)
{
}
int dbg_ports(void)
{
return 0;
}
void mpeg_stop(void)
{
}
void usb_acknowledge(void) void usb_acknowledge(void)
{ {
} }
@ -129,7 +113,3 @@ void usb_acknowledge(void)
void usb_wait_for_disconnect(void) void usb_wait_for_disconnect(void)
{ {
} }
void sys_poweroff(void)
{
}