diff options
-rw-r--r-- | bootloader/SOURCES | 2 | ||||
-rw-r--r-- | bootloader/common.c | 205 | ||||
-rw-r--r-- | bootloader/common.h | 34 | ||||
-rw-r--r-- | bootloader/ipod.c | 309 | ||||
-rw-r--r-- | bootloader/main-pp.c | 225 | ||||
-rw-r--r-- | firmware/export/pp5002.h | 4 | ||||
-rw-r--r-- | firmware/export/pp5020.h | 2 |
7 files changed, 362 insertions, 419 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES index b86365b429..76cb6931ef 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -1,8 +1,10 @@ #if defined(IPOD_ARCH) +common.c ipod.c #elif defined(GIGABEAT_F) gigabeat.c #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(SANSA_E200) +common.c main-pp.c #elif defined(ELIO_TPJ1022) tpj1022.c diff --git a/bootloader/common.c b/bootloader/common.c new file mode 100644 index 0000000000..410fd42cd8 --- /dev/null +++ b/bootloader/common.c @@ -0,0 +1,205 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "lcd.h" +#include "lcd-remote.h" +#include "font.h" +#include "system.h" +#include <stdarg.h> +#include <stdio.h> +#include "cpu.h" +#include "common.h" + +int line = 0; +#ifdef HAVE_REMOTE_LCD +int remote_line = 0; +#endif + +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 >= LCD_HEIGHT/SYSFONT_HEIGHT) + line = 0; +#ifdef HAVE_REMOTE_LCD + lcd_remote_puts(0, remote_line++, ptr); + lcd_remote_update(); + if(remote_line >= LCD_REMOTE_HEIGHT/SYSFONT_HEIGHT) + remote_line = 0; +#endif +} + +char *strerror(int error) +{ + switch(error) + { + case EOK: + return "OK"; + case EFILE_NOT_FOUND: + return "File not found"; + case EREAD_CHKSUM_FAILED: + return "Read failed (chksum)"; + case EREAD_MODEL_FAILED: + return "Read failed (model)"; + case EREAD_IMAGE_FAILED: + return "Read failed (image)"; + case EBAD_CHKSUM: + return "Bad checksum"; + case EFILE_TOO_BIG: + return "File too big"; + default: + return "Unknown"; + } +} + +/* Load firmware image in a format created by tools/scramble */ +int load_firmware(unsigned char* buf, char* firmware, int buffer_size) +{ + int fd; + int rc; + int len; + unsigned long chksum; + char model[5]; + unsigned long sum; + int i; + char filename[MAX_PATH]; + + snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware); + fd = open(filename, O_RDONLY); + if(fd < 0) + { + snprintf(filename,sizeof(filename),"/%s",firmware); + fd = open(filename, O_RDONLY); + if(fd < 0) + return EFILE_NOT_FOUND; + } + + len = filesize(fd) - 8; + + printf("Length: %x", len); + + if (len > buffer_size) + return EFILE_TOO_BIG; + + lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); + + rc = read(fd, &chksum, 4); + chksum=betoh32(chksum); /* Rockbox checksums are big-endian */ + if(rc < 4) + return EREAD_CHKSUM_FAILED; + + printf("Checksum: %x", chksum); + + rc = read(fd, model, 4); + if(rc < 4) + return EREAD_MODEL_FAILED; + + model[4] = 0; + + printf("Model name: %s", model); + printf("Loading %s", firmware); + + lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); + + rc = read(fd, buf, len); + if(rc < len) + return EREAD_IMAGE_FAILED; + + close(fd); + + sum = MODEL_NUMBER; + + for(i = 0;i < len;i++) { + sum += buf[i]; + } + + printf("Sum: %x", sum); + + if(sum != chksum) + return EBAD_CHKSUM; + + return len; +} + +/* Load raw binary image. */ +int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size) +{ + int fd; + int rc; + int len; + char filename[MAX_PATH]; + + snprintf(filename,sizeof(filename),"%s",firmware); + fd = open(filename, O_RDONLY); + if(fd < 0) + { + return EFILE_NOT_FOUND; + } + + len = filesize(fd); + + if (len > buffer_size) + return EFILE_TOO_BIG; + + rc = read(fd, buf, len); + if(rc < len) + return EREAD_IMAGE_FAILED; + + close(fd); + return len; +} + +/* These functions are present in the firmware library, but we reimplement + 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 sys_poweroff(void) +{ +} diff --git a/bootloader/common.h b/bootloader/common.h new file mode 100644 index 0000000000..7e001aa9ab --- /dev/null +++ b/bootloader/common.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* Error codes */ +#define EOK 0 +#define EFILE_NOT_FOUND -1 +#define EREAD_CHKSUM_FAILED -2 +#define EREAD_MODEL_FAILED -3 +#define EREAD_IMAGE_FAILED -4 +#define EBAD_CHKSUM -5 +#define EFILE_TOO_BIG -6 + +/* Functions common to all bootloaders */ +void reset_screen(void); +void printf(const char *format, ...); +char *strerror(int error); +int load_firmware(unsigned char* buf, char* firmware, int buffer_size); +int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size); diff --git a/bootloader/ipod.c b/bootloader/ipod.c index b1b3114ac9..73b4fffc71 100644 --- a/bootloader/ipod.c +++ b/bootloader/ipod.c @@ -39,16 +39,22 @@ #include "panic.h" #include "power.h" #include "file.h" +#include "common.h" #define XSC(X) #X #define SC(X) XSC(X) -#if (CONFIG_CPU == PP5020) -#define DRAM_START 0x10000000 -#else -#define IPOD_LCD_BASE 0xc0001000 -#define DRAM_START 0x28000000 -#endif +/* Maximum allowed firmware image size. The largest known current + (December 2006) firmware is about 7.5MB (Apple's firmware for the ipod video) + so we set this to 8MB. */ +#define MAX_LOADSIZE (8*1024*1024) + +/* A buffer to load the Linux kernel or Rockbox into */ +unsigned char *loadbuffer = (unsigned char *)DRAM_START; + +/* Bootloader version */ +char version[] = APPSVERSION; + #define IPOD_HW_REVISION (*((volatile unsigned long*)(0x00002084))) /* We copy the hardware revision to the last four bytes of SDRAM and then @@ -61,17 +67,6 @@ #define BUTTON_PLAY 4 #define BUTTON_HOLD 5 -/* Size of the buffer to store the loaded Rockbox/Linux/AppleOS image */ - -/* The largest known current (December 2006) firmware is about 7.5MB - (Apple's firmware for the ipod video) so we set this to 8MB. */ - -#define MAX_LOADSIZE (8*1024*1024) - -char version[] = APPSVERSION; - -int line=0; - #if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI) /* check if number of seconds has past */ int timer_check(int clock_start, unsigned int usecs) @@ -157,54 +152,6 @@ int opto_keypad_read(void) } #endif -char *strerror(int error) -{ - switch(error) - { - case 0: - return "OK"; - case -1: - return "File not found"; - case -2: - return "Read failed (chksum)"; - case -3: - return "Read failed (model)"; - case -4: - return "Read failed (image)"; - case -5: - return "Bad checksum"; - case -6: - return "File too big"; - default: - return "Unknown"; - } -} - -char printfbuf[256]; - -void reset_screen(void) -{ - lcd_clear_display(); - line = 0; -} - -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 >= (LCD_HEIGHT/SYSFONT_HEIGHT)) - line = 0; -} - static int key_pressed(void) { unsigned char state; @@ -240,101 +187,9 @@ bool button_hold(void) return (GPIOA_INPUT_VAL & 0x20)?false:true; } -int load_rockbox(unsigned char* buf, char* firmware) -{ - int fd; - int rc; - int len; - unsigned long chksum; - char model[5]; - unsigned long sum; - int i; - char filename[MAX_PATH]; - - snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware); - fd = open(filename, O_RDONLY); - if(fd < 0) - { - snprintf(filename,sizeof(filename),"/%s",firmware); - fd = open(filename, O_RDONLY); - if(fd < 0) - return -1; - } - - len = filesize(fd) - 8; - - if (len > MAX_LOADSIZE) - return -6; - - lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); - - rc = read(fd, &chksum, 4); - chksum=betoh32(chksum); /* Rockbox checksums are big-endian */ - if(rc < 4) - return -2; - - rc = read(fd, model, 4); - if(rc < 4) - return -3; - - model[4] = 0; - - printf("Model: %s", model); - printf("Checksum: %x", chksum); - printf("Loading %s", firmware); - - 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 len; -} - - -int load_linux(unsigned char* buf) { - int fd; - int rc; - int len; - - fd=open("/linux.bin",O_RDONLY); - if (fd < 0) - return -1; - - len=filesize(fd); - if (len > MAX_LOADSIZE) - return -6; - - rc=read(fd,buf,len); - - if (rc < len) - return -4; - - printf("Loaded Linux: %d bytes", len); - - return len; -} - - -/* A buffer to load the Linux kernel or Rockbox into */ -unsigned char loadbuffer[MAX_LOADSIZE]; - void fatal_error(void) { + extern int line; bool holdstatus=false; /* System font is 6 pixels wide */ @@ -423,7 +278,6 @@ void* main(void) button_init(); #endif - line=0; lcd_setfont(FONT_SYSFIXED); @@ -459,95 +313,74 @@ void* main(void) printf("Partition 1: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048); - /* See if there is an Apple firmware image in RAM */ - haveretailos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0); - - /* We don't load Rockbox if the hold button is enabled. */ - if (!button_was_held) { - /* Check for a keypress */ - i=key_pressed(); - - if ((i!=BUTTON_MENU) && (i!=BUTTON_PLAY)) { - printf("Loading Rockbox..."); - rc=load_rockbox(loadbuffer, BOOTFILE); - if (rc < 0) { - printf("Error!"); - printf("Can't load rockbox.ipod:"); - printf(strerror(rc)); - } else { - printf("Rockbox loaded."); - memcpy((void*)DRAM_START,loadbuffer,rc); - return (void*)DRAM_START; - } - } + + /* Check for a keypress */ + i=key_pressed(); - if (i==BUTTON_PLAY) { - printf("Loading Linux..."); - rc=load_linux(loadbuffer); - if (rc < 0) { - printf("Error!"); - printf("Can't load linux.bin:"); - printf(strerror(rc)); - } else { - memcpy((void*)DRAM_START,loadbuffer,rc); + if (button_was_held || (i==BUTTON_MENU)) { + /* If either the hold switch was on, or the Menu button was held, then + try the Apple firmware */ + + printf("Loading original firmware..."); + + /* First try an apple_os.ipod file on the FAT32 partition + (either in .rockbox or the root) + */ + + rc=load_firmware(loadbuffer, "apple_os.ipod", MAX_LOADSIZE); + + 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) { + /* We have a copy of the retailos in RAM, lets just run it. */ return (void*)DRAM_START; } + } else if (rc < EFILE_NOT_FOUND) { + printf("Error!"); + printf("Can't load apple_os.ipod:"); + printf(strerror(rc)); + } else if (rc > 0) { + printf("apple_os.ipod loaded."); + return (void*)DRAM_START; + } + + /* Everything failed - just loop forever */ + printf("No RetailOS detected"); + + } else if (i==BUTTON_PLAY) { + printf("Loading Linux..."); + rc=load_raw_firmware(loadbuffer, "/linux.bin", MAX_LOADSIZE); + if (rc < EOK) { + printf("Error!"); + printf("Can't load linux.bin:"); + printf(strerror(rc)); + } else { + return (void*)DRAM_START; + } + } else { + printf("Loading Rockbox..."); + rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); + if (rc < EOK) { + printf("Error!"); + printf("Can't load rockbox.ipod:"); + printf(strerror(rc)); + } else { + printf("Rockbox loaded."); + return (void*)DRAM_START; } } - - - /* If either the hold switch was on, or loading Rockbox/IPL - failed, then try the Apple firmware */ - - printf("Loading original firmware..."); - - /* First try an apple_os.ipod file on the FAT32 partition - (either in .rockbox or the root) - */ - - rc=load_rockbox(loadbuffer, "apple_os.ipod"); - - /* Only report errors if the file was found */ - if (rc < -1) { - printf("Error!"); - printf("Can't load apple_os.ipod:"); - printf(strerror(rc)); - } else if (rc > 0) { - printf("apple_os.ipod loaded."); - memcpy((void*)DRAM_START,loadbuffer,rc); - return (void*)DRAM_START; - } - - if (haveretailos) { - /* We have a copy of the retailos in RAM, lets just run it. */ - return (void*)DRAM_START; - } - - /* Everything failed - just loop forever */ - printf("No RetailOS detected"); - + + /* If we get to here, then we haven't been able to load any firmware */ fatal_error(); - + /* We never get here, but keep gcc happy */ return (void*)0; } /* These functions are present in the firmware library, but we reimplement 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) { } @@ -555,7 +388,3 @@ void usb_acknowledge(void) void usb_wait_for_disconnect(void) { } - -void sys_poweroff(void) -{ -} diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c index 1da24b7d9b..a02510e31c 100644 --- a/bootloader/main-pp.c +++ b/bootloader/main-pp.c @@ -19,156 +19,27 @@ * KIND, either express or implied. * ****************************************************************************/ -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> +#include "common.h" #include "cpu.h" +#include "file.h" #include "system.h" -#include "lcd.h" #include "kernel.h" -#include "thread.h" -#include "ata.h" -#include "fat.h" -#include "disk.h" +#include "lcd.h" #include "font.h" -#include "adc.h" -#include "backlight.h" +#include "ata.h" #include "button.h" -#include "panic.h" +#include "disk.h" #include "power.h" -#include "file.h" -/* Size of the buffer to store the loaded firmware image */ +/* Maximum allowed firmware image size. 10MB is more than enough */ #define MAX_LOADSIZE (10*1024*1024) -/* A buffer to load the iriver firmware or Rockbox into */ -unsigned char loadbuffer[MAX_LOADSIZE]; +/* A buffer to load the original firmware or Rockbox into */ +unsigned char *loadbuffer = (unsigned char *)DRAM_START; +/* Bootloader version */ char version[] = APPSVERSION; -#define DRAM_START 0x10000000 - -int line=0; -char printfbuf[256]; - -void reset_screen(void) -{ - lcd_clear_display(); - line = 0; -} - -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 >= (LCD_HEIGHT/SYSFONT_HEIGHT)) - line = 0; -} - -/* Load original mi4 firmware. This function expects a file called - "/System/OF.bin" on the player. It should be a mi4 firmware decrypted - and header stripped using mi4code. It reads the file in to a memory - buffer called buf. The rest of the loading is done in main() and crt0.S -*/ -int load_original_firmware(unsigned char* buf) -{ - int fd; - int rc; - int len; - - fd = open("/System/OF.bin", O_RDONLY); - - len = filesize(fd); - - if (len > MAX_LOADSIZE) - return -6; - - rc = read(fd, buf, len); - if(rc < len) - return -4; - - close(fd); - return len; -} - -/* Load Rockbox firmware (rockbox.*) */ -int load_rockbox(unsigned char* buf) -{ - int fd; - int rc; - int len; - unsigned long chksum; - char model[5]; - unsigned long sum; - int i; - - 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); - - if (len > MAX_LOADSIZE) - return -6; - - lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); - - rc = read(fd, &chksum, 4); - chksum=betoh32(chksum); /* Rockbox checksums are big-endian */ - 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); - - 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 len; -} - void* main(void) { char buf[256]; @@ -183,8 +54,6 @@ void* main(void) font_init(); button_init(); - line=0; - lcd_setfont(FONT_SYSFIXED); printf("Rockbox boot loader"); @@ -193,18 +62,20 @@ void* main(void) i=ata_init(); if (i==0) { - identify_info=ata_get_identify(); - /* Show model */ - for (i=0; i < 20; i++) { - ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); - } - buf[40]=0; - for (i=39; i && buf[i]==' '; i--) { - buf[i]=0; - } - printf(buf); + identify_info=ata_get_identify(); + /* Show model */ + for (i=0; i < 20; i++) { + ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); + } + buf[40]=0; + for (i=39; i && buf[i]==' '; i--) { + buf[i]=0; + } + printf(buf); } else { - printf("ATA: %d", i); + printf("ATA error: %d", i); + sleep(HZ*5); + power_off(); } disk_init(); @@ -212,6 +83,8 @@ void* main(void) if (rc<=0) { printf("No partition found"); + sleep(HZ*5); + power_off(); } pinfo = disk_partinfo(0); @@ -220,39 +93,37 @@ void* main(void) i=button_read_device(); if(i==BUTTON_LEFT) { + /* Load original mi4 firmware. This expects a file called + "/System/OF.bin" on the player. It should be a mi4 firmware decrypted + and header stripped using mi4code. It reads the file in to a memory + buffer called loadbuffer. The rest of the loading is done in crt0.S + */ printf("Loading original firmware..."); - rc=load_original_firmware(loadbuffer); + rc=load_raw_firmware(loadbuffer, "/System/OF.bin", MAX_LOADSIZE); + if (rc < EOK) { + printf("Error!"); + printf("Can't load /System/OF.bin:"); + printf(strerror(rc)); + sleep(HZ*5); + power_off(); + } } else { printf("Loading Rockbox..."); - rc=load_rockbox(loadbuffer); + rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); + if (rc < EOK) { + printf("Error!"); + printf("Can't load %s:", BOOTFILE); + printf(strerror(rc)); + sleep(HZ*5); + power_off(); + } } - - if (rc < 0) { - printf("Rockbox error: %d",rc); - while(1) {} - } - - memcpy((void*)DRAM_START,loadbuffer,rc); - return (void*)DRAM_START; + return (void*)loadbuffer; } /* These functions are present in the firmware library, but we reimplement 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) { } @@ -260,7 +131,3 @@ void usb_acknowledge(void) void usb_wait_for_disconnect(void) { } - -void sys_poweroff(void) -{ -} diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index 41e8f4cce2..c7606886bc 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h @@ -20,6 +20,10 @@ #define __PP5002_H__ /* All info gleaned and/or copied from the iPodLinux project. */ +#define DRAM_START 0x28000000 + +#define IPOD_LCD_BASE 0xc0001000 + #define CPU_CTL (*(volatile unsigned char *)(0xcf004054)) #define COP_CTL (*(volatile unsigned char *)(0xcf004058)) diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index a71ca7ef05..4e0e6eac2a 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -20,6 +20,8 @@ #define __PP5020_H__ /* All info gleaned and/or copied from the iPodLinux project. */ +#define DRAM_START 0x10000000 + #define CPU_CTL (*(volatile unsigned long *)(0x60007000)) #define COP_CTL (*(volatile unsigned long *)(0x60007004)) |