summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2007-01-28 18:42:11 +0000
committerBarry Wardell <rockbox@barrywardell.net>2007-01-28 18:42:11 +0000
commit84b509dc43cf84ef16fcd4a57b167351f146cd11 (patch)
tree57eca4b44db56e11c1a3d9dde5d0e4ef8e830686
parent6c3a44643590f8cbc925375c2dc8393cc7f9d55e (diff)
downloadrockbox-84b509dc43cf84ef16fcd4a57b167351f146cd11.tar.gz
rockbox-84b509dc43cf84ef16fcd4a57b167351f146cd11.zip
FS#6554. Move bootloader code into a common file. Only PortalPlayer devices (iPods, H10, Sansa) are affected for the moment. Someone with access to (and no fear of bricking) an X5, H100, H300 and Gigabeat should try to adapt those bootloaders to also use the code in common.c. The (non-working) patch in the tracker would be a good place to start with this.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12136 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/SOURCES2
-rw-r--r--bootloader/common.c205
-rw-r--r--bootloader/common.h34
-rw-r--r--bootloader/ipod.c309
-rw-r--r--bootloader/main-pp.c225
-rw-r--r--firmware/export/pp5002.h4
-rw-r--r--firmware/export/pp5020.h2
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 @@
1#if defined(IPOD_ARCH) 1#if defined(IPOD_ARCH)
2common.c
2ipod.c 3ipod.c
3#elif defined(GIGABEAT_F) 4#elif defined(GIGABEAT_F)
4gigabeat.c 5gigabeat.c
5#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(SANSA_E200) 6#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(SANSA_E200)
7common.c
6main-pp.c 8main-pp.c
7#elif defined(ELIO_TPJ1022) 9#elif defined(ELIO_TPJ1022)
8tpj1022.c 10tpj1022.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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "lcd.h"
20#include "lcd-remote.h"
21#include "font.h"
22#include "system.h"
23#include <stdarg.h>
24#include <stdio.h>
25#include "cpu.h"
26#include "common.h"
27
28int line = 0;
29#ifdef HAVE_REMOTE_LCD
30int remote_line = 0;
31#endif
32
33char printfbuf[256];
34
35void reset_screen(void)
36{
37 lcd_clear_display();
38 line = 0;
39#ifdef HAVE_REMOTE_LCD
40 lcd_remote_clear_display();
41 remote_line = 0;
42#endif
43}
44
45void printf(const char *format, ...)
46{
47 int len;
48 unsigned char *ptr;
49 va_list ap;
50 va_start(ap, format);
51
52 ptr = printfbuf;
53 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
54 va_end(ap);
55
56 lcd_puts(0, line++, ptr);
57 lcd_update();
58 if(line >= LCD_HEIGHT/SYSFONT_HEIGHT)
59 line = 0;
60#ifdef HAVE_REMOTE_LCD
61 lcd_remote_puts(0, remote_line++, ptr);
62 lcd_remote_update();
63 if(remote_line >= LCD_REMOTE_HEIGHT/SYSFONT_HEIGHT)
64 remote_line = 0;
65#endif
66}
67
68char *strerror(int error)
69{
70 switch(error)
71 {
72 case EOK:
73 return "OK";
74 case EFILE_NOT_FOUND:
75 return "File not found";
76 case EREAD_CHKSUM_FAILED:
77 return "Read failed (chksum)";
78 case EREAD_MODEL_FAILED:
79 return "Read failed (model)";
80 case EREAD_IMAGE_FAILED:
81 return "Read failed (image)";
82 case EBAD_CHKSUM:
83 return "Bad checksum";
84 case EFILE_TOO_BIG:
85 return "File too big";
86 default:
87 return "Unknown";
88 }
89}
90
91/* Load firmware image in a format created by tools/scramble */
92int load_firmware(unsigned char* buf, char* firmware, int buffer_size)
93{
94 int fd;
95 int rc;
96 int len;
97 unsigned long chksum;
98 char model[5];
99 unsigned long sum;
100 int i;
101 char filename[MAX_PATH];
102
103 snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware);
104 fd = open(filename, O_RDONLY);
105 if(fd < 0)
106 {
107 snprintf(filename,sizeof(filename),"/%s",firmware);
108 fd = open(filename, O_RDONLY);
109 if(fd < 0)
110 return EFILE_NOT_FOUND;
111 }
112
113 len = filesize(fd) - 8;
114
115 printf("Length: %x", len);
116
117 if (len > buffer_size)
118 return EFILE_TOO_BIG;
119
120 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
121
122 rc = read(fd, &chksum, 4);
123 chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
124 if(rc < 4)
125 return EREAD_CHKSUM_FAILED;
126
127 printf("Checksum: %x", chksum);
128
129 rc = read(fd, model, 4);
130 if(rc < 4)
131 return EREAD_MODEL_FAILED;
132
133 model[4] = 0;
134
135 printf("Model name: %s", model);
136 printf("Loading %s", firmware);
137
138 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
139
140 rc = read(fd, buf, len);
141 if(rc < len)
142 return EREAD_IMAGE_FAILED;
143
144 close(fd);
145
146 sum = MODEL_NUMBER;
147
148 for(i = 0;i < len;i++) {
149 sum += buf[i];
150 }
151
152 printf("Sum: %x", sum);
153
154 if(sum != chksum)
155 return EBAD_CHKSUM;
156
157 return len;
158}
159
160/* Load raw binary image. */
161int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size)
162{
163 int fd;
164 int rc;
165 int len;
166 char filename[MAX_PATH];
167
168 snprintf(filename,sizeof(filename),"%s",firmware);
169 fd = open(filename, O_RDONLY);
170 if(fd < 0)
171 {
172 return EFILE_NOT_FOUND;
173 }
174
175 len = filesize(fd);
176
177 if (len > buffer_size)
178 return EFILE_TOO_BIG;
179
180 rc = read(fd, buf, len);
181 if(rc < len)
182 return EREAD_IMAGE_FAILED;
183
184 close(fd);
185 return len;
186}
187
188/* These functions are present in the firmware library, but we reimplement
189 them here because the originals do a lot more than we want */
190void reset_poweroff_timer(void)
191{
192}
193
194int dbg_ports(void)
195{
196 return 0;
197}
198
199void mpeg_stop(void)
200{
201}
202
203void sys_poweroff(void)
204{
205}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20/* Error codes */
21#define EOK 0
22#define EFILE_NOT_FOUND -1
23#define EREAD_CHKSUM_FAILED -2
24#define EREAD_MODEL_FAILED -3
25#define EREAD_IMAGE_FAILED -4
26#define EBAD_CHKSUM -5
27#define EFILE_TOO_BIG -6
28
29/* Functions common to all bootloaders */
30void reset_screen(void);
31void printf(const char *format, ...);
32char *strerror(int error);
33int load_firmware(unsigned char* buf, char* firmware, int buffer_size);
34int 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 @@
39#include "panic.h" 39#include "panic.h"
40#include "power.h" 40#include "power.h"
41#include "file.h" 41#include "file.h"
42#include "common.h"
42 43
43#define XSC(X) #X 44#define XSC(X) #X
44#define SC(X) XSC(X) 45#define SC(X) XSC(X)
45 46
46#if (CONFIG_CPU == PP5020) 47/* Maximum allowed firmware image size. The largest known current
47#define DRAM_START 0x10000000 48 (December 2006) firmware is about 7.5MB (Apple's firmware for the ipod video)
48#else 49 so we set this to 8MB. */
49#define IPOD_LCD_BASE 0xc0001000 50#define MAX_LOADSIZE (8*1024*1024)
50#define DRAM_START 0x28000000 51
51#endif 52/* A buffer to load the Linux kernel or Rockbox into */
53unsigned char *loadbuffer = (unsigned char *)DRAM_START;
54
55/* Bootloader version */
56char version[] = APPSVERSION;
57
52#define IPOD_HW_REVISION (*((volatile unsigned long*)(0x00002084))) 58#define IPOD_HW_REVISION (*((volatile unsigned long*)(0x00002084)))
53 59
54/* We copy the hardware revision to the last four bytes of SDRAM and then 60/* We copy the hardware revision to the last four bytes of SDRAM and then
@@ -61,17 +67,6 @@
61#define BUTTON_PLAY 4 67#define BUTTON_PLAY 4
62#define BUTTON_HOLD 5 68#define BUTTON_HOLD 5
63 69
64/* Size of the buffer to store the loaded Rockbox/Linux/AppleOS image */
65
66/* The largest known current (December 2006) firmware is about 7.5MB
67 (Apple's firmware for the ipod video) so we set this to 8MB. */
68
69#define MAX_LOADSIZE (8*1024*1024)
70
71char version[] = APPSVERSION;
72
73int line=0;
74
75#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI) 70#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
76/* check if number of seconds has past */ 71/* check if number of seconds has past */
77int timer_check(int clock_start, unsigned int usecs) 72int timer_check(int clock_start, unsigned int usecs)
@@ -157,54 +152,6 @@ int opto_keypad_read(void)
157} 152}
158#endif 153#endif
159 154
160char *strerror(int error)
161{
162 switch(error)
163 {
164 case 0:
165 return "OK";
166 case -1:
167 return "File not found";
168 case -2:
169 return "Read failed (chksum)";
170 case -3:
171 return "Read failed (model)";
172 case -4:
173 return "Read failed (image)";
174 case -5:
175 return "Bad checksum";
176 case -6:
177 return "File too big";
178 default:
179 return "Unknown";
180 }
181}
182
183char printfbuf[256];
184
185void reset_screen(void)
186{
187 lcd_clear_display();
188 line = 0;
189}
190
191void printf(const char *format, ...)
192{
193 int len;
194 unsigned char *ptr;
195 va_list ap;
196 va_start(ap, format);
197
198 ptr = printfbuf;
199 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
200 va_end(ap);
201
202 lcd_puts(0, line++, ptr);
203 lcd_update();
204 if(line >= (LCD_HEIGHT/SYSFONT_HEIGHT))
205 line = 0;
206}
207
208static int key_pressed(void) 155static int key_pressed(void)
209{ 156{
210 unsigned char state; 157 unsigned char state;
@@ -240,101 +187,9 @@ bool button_hold(void)
240 return (GPIOA_INPUT_VAL & 0x20)?false:true; 187 return (GPIOA_INPUT_VAL & 0x20)?false:true;
241} 188}
242 189
243int load_rockbox(unsigned char* buf, char* firmware)
244{
245 int fd;
246 int rc;
247 int len;
248 unsigned long chksum;
249 char model[5];
250 unsigned long sum;
251 int i;
252 char filename[MAX_PATH];
253
254 snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware);
255 fd = open(filename, O_RDONLY);
256 if(fd < 0)
257 {
258 snprintf(filename,sizeof(filename),"/%s",firmware);
259 fd = open(filename, O_RDONLY);
260 if(fd < 0)
261 return -1;
262 }
263
264 len = filesize(fd) - 8;
265
266 if (len > MAX_LOADSIZE)
267 return -6;
268
269 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
270
271 rc = read(fd, &chksum, 4);
272 chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
273 if(rc < 4)
274 return -2;
275
276 rc = read(fd, model, 4);
277 if(rc < 4)
278 return -3;
279
280 model[4] = 0;
281
282 printf("Model: %s", model);
283 printf("Checksum: %x", chksum);
284 printf("Loading %s", firmware);
285
286 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
287
288 rc = read(fd, buf, len);
289 if(rc < len)
290 return -4;
291
292 close(fd);
293
294 sum = MODEL_NUMBER;
295
296 for(i = 0;i < len;i++) {
297 sum += buf[i];
298 }
299
300 printf("Sum: %x", sum);
301
302 if(sum != chksum)
303 return -5;
304
305 return len;
306}
307
308
309int load_linux(unsigned char* buf) {
310 int fd;
311 int rc;
312 int len;
313
314 fd=open("/linux.bin",O_RDONLY);
315 if (fd < 0)
316 return -1;
317
318 len=filesize(fd);
319 if (len > MAX_LOADSIZE)
320 return -6;
321
322 rc=read(fd,buf,len);
323
324 if (rc < len)
325 return -4;
326
327 printf("Loaded Linux: %d bytes", len);
328
329 return len;
330}
331
332
333/* A buffer to load the Linux kernel or Rockbox into */
334unsigned char loadbuffer[MAX_LOADSIZE];
335
336void fatal_error(void) 190void fatal_error(void)
337{ 191{
192 extern int line;
338 bool holdstatus=false; 193 bool holdstatus=false;
339 194
340 /* System font is 6 pixels wide */ 195 /* System font is 6 pixels wide */
@@ -423,7 +278,6 @@ void* main(void)
423 button_init(); 278 button_init();
424#endif 279#endif
425 280
426 line=0;
427 281
428 lcd_setfont(FONT_SYSFIXED); 282 lcd_setfont(FONT_SYSFIXED);
429 283
@@ -459,95 +313,74 @@ void* main(void)
459 printf("Partition 1: 0x%02x %ld MB", 313 printf("Partition 1: 0x%02x %ld MB",
460 pinfo->type, pinfo->size / 2048); 314 pinfo->type, pinfo->size / 2048);
461 315
462 /* See if there is an Apple firmware image in RAM */ 316
463 haveretailos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0); 317 /* Check for a keypress */
464 318 i=key_pressed();
465 /* We don't load Rockbox if the hold button is enabled. */
466 if (!button_was_held) {
467 /* Check for a keypress */
468 i=key_pressed();
469
470 if ((i!=BUTTON_MENU) && (i!=BUTTON_PLAY)) {
471 printf("Loading Rockbox...");
472 rc=load_rockbox(loadbuffer, BOOTFILE);
473 if (rc < 0) {
474 printf("Error!");
475 printf("Can't load rockbox.ipod:");
476 printf(strerror(rc));
477 } else {
478 printf("Rockbox loaded.");
479 memcpy((void*)DRAM_START,loadbuffer,rc);
480 return (void*)DRAM_START;
481 }
482 }
483 319
484 if (i==BUTTON_PLAY) { 320 if (button_was_held || (i==BUTTON_MENU)) {
485 printf("Loading Linux..."); 321 /* If either the hold switch was on, or the Menu button was held, then
486 rc=load_linux(loadbuffer); 322 try the Apple firmware */
487 if (rc < 0) { 323
488 printf("Error!"); 324 printf("Loading original firmware...");
489 printf("Can't load linux.bin:"); 325
490 printf(strerror(rc)); 326 /* First try an apple_os.ipod file on the FAT32 partition
491 } else { 327 (either in .rockbox or the root)
492 memcpy((void*)DRAM_START,loadbuffer,rc); 328 */
329
330 rc=load_firmware(loadbuffer, "apple_os.ipod", MAX_LOADSIZE);
331
332 if(rc==EFILE_NOT_FOUND) {
333 /* If apple_os.ipod doesn't exist, then check if there is an Apple
334 firmware image in RAM */
335 haveretailos = (memcmp((void*)(DRAM_START+0x20),"portalplayer",12)==0);
336 if (haveretailos) {
337 /* We have a copy of the retailos in RAM, lets just run it. */
493 return (void*)DRAM_START; 338 return (void*)DRAM_START;
494 } 339 }
340 } else if (rc < EFILE_NOT_FOUND) {
341 printf("Error!");
342 printf("Can't load apple_os.ipod:");
343 printf(strerror(rc));
344 } else if (rc > 0) {
345 printf("apple_os.ipod loaded.");
346 return (void*)DRAM_START;
347 }
348
349 /* Everything failed - just loop forever */
350 printf("No RetailOS detected");
351
352 } else if (i==BUTTON_PLAY) {
353 printf("Loading Linux...");
354 rc=load_raw_firmware(loadbuffer, "/linux.bin", MAX_LOADSIZE);
355 if (rc < EOK) {
356 printf("Error!");
357 printf("Can't load linux.bin:");
358 printf(strerror(rc));
359 } else {
360 return (void*)DRAM_START;
361 }
362 } else {
363 printf("Loading Rockbox...");
364 rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
365 if (rc < EOK) {
366 printf("Error!");
367 printf("Can't load rockbox.ipod:");
368 printf(strerror(rc));
369 } else {
370 printf("Rockbox loaded.");
371 return (void*)DRAM_START;
495 } 372 }
496 } 373 }
497 374
498 375 /* If we get to here, then we haven't been able to load any firmware */
499 /* If either the hold switch was on, or loading Rockbox/IPL
500 failed, then try the Apple firmware */
501
502 printf("Loading original firmware...");
503
504 /* First try an apple_os.ipod file on the FAT32 partition
505 (either in .rockbox or the root)
506 */
507
508 rc=load_rockbox(loadbuffer, "apple_os.ipod");
509
510 /* Only report errors if the file was found */
511 if (rc < -1) {
512 printf("Error!");
513 printf("Can't load apple_os.ipod:");
514 printf(strerror(rc));
515 } else if (rc > 0) {
516 printf("apple_os.ipod loaded.");
517 memcpy((void*)DRAM_START,loadbuffer,rc);
518 return (void*)DRAM_START;
519 }
520
521 if (haveretailos) {
522 /* We have a copy of the retailos in RAM, lets just run it. */
523 return (void*)DRAM_START;
524 }
525
526 /* Everything failed - just loop forever */
527 printf("No RetailOS detected");
528
529 fatal_error(); 376 fatal_error();
530 377
531 /* We never get here, but keep gcc happy */ 378 /* We never get here, but keep gcc happy */
532 return (void*)0; 379 return (void*)0;
533} 380}
534 381
535/* These functions are present in the firmware library, but we reimplement 382/* These functions are present in the firmware library, but we reimplement
536 them here because the originals do a lot more than we want */ 383 them here because the originals do a lot more than we want */
537
538void reset_poweroff_timer(void)
539{
540}
541
542int dbg_ports(void)
543{
544 return 0;
545}
546
547void mpeg_stop(void)
548{
549}
550
551void usb_acknowledge(void) 384void usb_acknowledge(void)
552{ 385{
553} 386}
@@ -555,7 +388,3 @@ void usb_acknowledge(void)
555void usb_wait_for_disconnect(void) 388void usb_wait_for_disconnect(void)
556{ 389{
557} 390}
558
559void sys_poweroff(void)
560{
561}
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 @@
19 * KIND, either express or implied. 19 * KIND, either express or implied.
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22#include "config.h" 22#include "common.h"
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include <stdarg.h>
28#include "cpu.h" 23#include "cpu.h"
24#include "file.h"
29#include "system.h" 25#include "system.h"
30#include "lcd.h"
31#include "kernel.h" 26#include "kernel.h"
32#include "thread.h" 27#include "lcd.h"
33#include "ata.h"
34#include "fat.h"
35#include "disk.h"
36#include "font.h" 28#include "font.h"
37#include "adc.h" 29#include "ata.h"
38#include "backlight.h"
39#include "button.h" 30#include "button.h"
40#include "panic.h" 31#include "disk.h"
41#include "power.h" 32#include "power.h"
42#include "file.h"
43 33
44/* Size of the buffer to store the loaded firmware image */ 34/* Maximum allowed firmware image size. 10MB is more than enough */
45#define MAX_LOADSIZE (10*1024*1024) 35#define MAX_LOADSIZE (10*1024*1024)
46 36
47/* A buffer to load the iriver firmware or Rockbox into */ 37/* A buffer to load the original firmware or Rockbox into */
48unsigned char loadbuffer[MAX_LOADSIZE]; 38unsigned char *loadbuffer = (unsigned char *)DRAM_START;
49 39
40/* Bootloader version */
50char version[] = APPSVERSION; 41char version[] = APPSVERSION;
51 42
52#define DRAM_START 0x10000000
53
54int line=0;
55char printfbuf[256];
56
57void reset_screen(void)
58{
59 lcd_clear_display();
60 line = 0;
61}
62
63void printf(const char *format, ...)
64{
65 int len;
66 unsigned char *ptr;
67 va_list ap;
68 va_start(ap, format);
69
70
71 ptr = printfbuf;
72 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
73 va_end(ap);
74
75 lcd_puts(0, line++, ptr);
76 lcd_update();
77 if(line >= (LCD_HEIGHT/SYSFONT_HEIGHT))
78 line = 0;
79}
80
81/* Load original mi4 firmware. This function expects a file called
82 "/System/OF.bin" on the player. It should be a mi4 firmware decrypted
83 and header stripped using mi4code. It reads the file in to a memory
84 buffer called buf. The rest of the loading is done in main() and crt0.S
85*/
86int load_original_firmware(unsigned char* buf)
87{
88 int fd;
89 int rc;
90 int len;
91
92 fd = open("/System/OF.bin", O_RDONLY);
93
94 len = filesize(fd);
95
96 if (len > MAX_LOADSIZE)
97 return -6;
98
99 rc = read(fd, buf, len);
100 if(rc < len)
101 return -4;
102
103 close(fd);
104 return len;
105}
106
107/* Load Rockbox firmware (rockbox.*) */
108int load_rockbox(unsigned char* buf)
109{
110 int fd;
111 int rc;
112 int len;
113 unsigned long chksum;
114 char model[5];
115 unsigned long sum;
116 int i;
117
118 fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
119 if(fd < 0)
120 {
121 fd = open("/" BOOTFILE, O_RDONLY);
122 if(fd < 0)
123 return -1;
124 }
125
126 len = filesize(fd) - 8;
127
128 printf("Length: %x", len);
129
130 if (len > MAX_LOADSIZE)
131 return -6;
132
133 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
134
135 rc = read(fd, &chksum, 4);
136 chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
137 if(rc < 4)
138 return -2;
139
140 printf("Checksum: %x", chksum);
141
142 rc = read(fd, model, 4);
143 if(rc < 4)
144 return -3;
145
146 model[4] = 0;
147
148 printf("Model name: %s", model);
149
150 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
151
152 rc = read(fd, buf, len);
153 if(rc < len)
154 return -4;
155
156 close(fd);
157
158 sum = MODEL_NUMBER;
159
160 for(i = 0;i < len;i++) {
161 sum += buf[i];
162 }
163
164 printf("Sum: %x", sum);
165
166 if(sum != chksum)
167 return -5;
168
169 return len;
170}
171
172void* main(void) 43void* main(void)
173{ 44{
174 char buf[256]; 45 char buf[256];
@@ -183,8 +54,6 @@ void* main(void)
183 font_init(); 54 font_init();
184 button_init(); 55 button_init();
185 56
186 line=0;
187
188 lcd_setfont(FONT_SYSFIXED); 57 lcd_setfont(FONT_SYSFIXED);
189 58
190 printf("Rockbox boot loader"); 59 printf("Rockbox boot loader");
@@ -193,18 +62,20 @@ void* main(void)
193 62
194 i=ata_init(); 63 i=ata_init();
195 if (i==0) { 64 if (i==0) {
196 identify_info=ata_get_identify(); 65 identify_info=ata_get_identify();
197 /* Show model */ 66 /* Show model */
198 for (i=0; i < 20; i++) { 67 for (i=0; i < 20; i++) {
199 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); 68 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
200 } 69 }
201 buf[40]=0; 70 buf[40]=0;
202 for (i=39; i && buf[i]==' '; i--) { 71 for (i=39; i && buf[i]==' '; i--) {
203 buf[i]=0; 72 buf[i]=0;
204 } 73 }
205 printf(buf); 74 printf(buf);
206 } else { 75 } else {
207 printf("ATA: %d", i); 76 printf("ATA error: %d", i);
77 sleep(HZ*5);
78 power_off();
208 } 79 }
209 80
210 disk_init(); 81 disk_init();
@@ -212,6 +83,8 @@ void* main(void)
212 if (rc<=0) 83 if (rc<=0)
213 { 84 {
214 printf("No partition found"); 85 printf("No partition found");
86 sleep(HZ*5);
87 power_off();
215 } 88 }
216 89
217 pinfo = disk_partinfo(0); 90 pinfo = disk_partinfo(0);
@@ -220,39 +93,37 @@ void* main(void)
220 i=button_read_device(); 93 i=button_read_device();
221 if(i==BUTTON_LEFT) 94 if(i==BUTTON_LEFT)
222 { 95 {
96 /* Load original mi4 firmware. This expects a file called
97 "/System/OF.bin" on the player. It should be a mi4 firmware decrypted
98 and header stripped using mi4code. It reads the file in to a memory
99 buffer called loadbuffer. The rest of the loading is done in crt0.S
100 */
223 printf("Loading original firmware..."); 101 printf("Loading original firmware...");
224 rc=load_original_firmware(loadbuffer); 102 rc=load_raw_firmware(loadbuffer, "/System/OF.bin", MAX_LOADSIZE);
103 if (rc < EOK) {
104 printf("Error!");
105 printf("Can't load /System/OF.bin:");
106 printf(strerror(rc));
107 sleep(HZ*5);
108 power_off();
109 }
225 } else { 110 } else {
226 printf("Loading Rockbox..."); 111 printf("Loading Rockbox...");
227 rc=load_rockbox(loadbuffer); 112 rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
113 if (rc < EOK) {
114 printf("Error!");
115 printf("Can't load %s:", BOOTFILE);
116 printf(strerror(rc));
117 sleep(HZ*5);
118 power_off();
119 }
228 } 120 }
229
230 if (rc < 0) {
231 printf("Rockbox error: %d",rc);
232 while(1) {}
233 }
234
235 memcpy((void*)DRAM_START,loadbuffer,rc);
236 121
237 return (void*)DRAM_START; 122 return (void*)loadbuffer;
238} 123}
239 124
240/* These functions are present in the firmware library, but we reimplement 125/* These functions are present in the firmware library, but we reimplement
241 them here because the originals do a lot more than we want */ 126 them here because the originals do a lot more than we want */
242
243void reset_poweroff_timer(void)
244{
245}
246
247int dbg_ports(void)
248{
249 return 0;
250}
251
252void mpeg_stop(void)
253{
254}
255
256void usb_acknowledge(void) 127void usb_acknowledge(void)
257{ 128{
258} 129}
@@ -260,7 +131,3 @@ void usb_acknowledge(void)
260void usb_wait_for_disconnect(void) 131void usb_wait_for_disconnect(void)
261{ 132{
262} 133}
263
264void sys_poweroff(void)
265{
266}
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 @@
20#define __PP5002_H__ 20#define __PP5002_H__
21 21
22/* All info gleaned and/or copied from the iPodLinux project. */ 22/* All info gleaned and/or copied from the iPodLinux project. */
23#define DRAM_START 0x28000000
24
25#define IPOD_LCD_BASE 0xc0001000
26
23#define CPU_CTL (*(volatile unsigned char *)(0xcf004054)) 27#define CPU_CTL (*(volatile unsigned char *)(0xcf004054))
24#define COP_CTL (*(volatile unsigned char *)(0xcf004058)) 28#define COP_CTL (*(volatile unsigned char *)(0xcf004058))
25 29
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 @@
20#define __PP5020_H__ 20#define __PP5020_H__
21 21
22/* All info gleaned and/or copied from the iPodLinux project. */ 22/* All info gleaned and/or copied from the iPodLinux project. */
23#define DRAM_START 0x10000000
24
23#define CPU_CTL (*(volatile unsigned long *)(0x60007000)) 25#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
24#define COP_CTL (*(volatile unsigned long *)(0x60007004)) 26#define COP_CTL (*(volatile unsigned long *)(0x60007004))
25 27