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 @@ | |||
1 | #if defined(IPOD_ARCH) | 1 | #if defined(IPOD_ARCH) |
2 | common.c | ||
2 | ipod.c | 3 | ipod.c |
3 | #elif defined(GIGABEAT_F) | 4 | #elif defined(GIGABEAT_F) |
4 | gigabeat.c | 5 | gigabeat.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) |
7 | common.c | ||
6 | main-pp.c | 8 | main-pp.c |
7 | #elif defined(ELIO_TPJ1022) | 9 | #elif defined(ELIO_TPJ1022) |
8 | tpj1022.c | 10 | 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 @@ | |||
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 | |||
28 | int line = 0; | ||
29 | #ifdef HAVE_REMOTE_LCD | ||
30 | int remote_line = 0; | ||
31 | #endif | ||
32 | |||
33 | char printfbuf[256]; | ||
34 | |||
35 | void 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 | |||
45 | void 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 | |||
68 | char *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 */ | ||
92 | int 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. */ | ||
161 | int 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 */ | ||
190 | void reset_poweroff_timer(void) | ||
191 | { | ||
192 | } | ||
193 | |||
194 | int dbg_ports(void) | ||
195 | { | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | void mpeg_stop(void) | ||
200 | { | ||
201 | } | ||
202 | |||
203 | void 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 */ | ||
30 | void reset_screen(void); | ||
31 | void printf(const char *format, ...); | ||
32 | char *strerror(int error); | ||
33 | int load_firmware(unsigned char* buf, char* firmware, int buffer_size); | ||
34 | 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 @@ | |||
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 */ |
53 | unsigned char *loadbuffer = (unsigned char *)DRAM_START; | ||
54 | |||
55 | /* Bootloader version */ | ||
56 | char 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 | |||
71 | char version[] = APPSVERSION; | ||
72 | |||
73 | int 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 */ |
77 | int timer_check(int clock_start, unsigned int usecs) | 72 | int 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 | ||
160 | char *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 | |||
183 | char printfbuf[256]; | ||
184 | |||
185 | void reset_screen(void) | ||
186 | { | ||
187 | lcd_clear_display(); | ||
188 | line = 0; | ||
189 | } | ||
190 | |||
191 | void 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 | |||
208 | static int key_pressed(void) | 155 | static 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 | ||
243 | int 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 | |||
309 | int 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 */ | ||
334 | unsigned char loadbuffer[MAX_LOADSIZE]; | ||
335 | |||
336 | void fatal_error(void) | 190 | void 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 | |||
538 | void reset_poweroff_timer(void) | ||
539 | { | ||
540 | } | ||
541 | |||
542 | int dbg_ports(void) | ||
543 | { | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | void mpeg_stop(void) | ||
548 | { | ||
549 | } | ||
550 | |||
551 | void usb_acknowledge(void) | 384 | void usb_acknowledge(void) |
552 | { | 385 | { |
553 | } | 386 | } |
@@ -555,7 +388,3 @@ void usb_acknowledge(void) | |||
555 | void usb_wait_for_disconnect(void) | 388 | void usb_wait_for_disconnect(void) |
556 | { | 389 | { |
557 | } | 390 | } |
558 | |||
559 | void 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 */ |
48 | unsigned char loadbuffer[MAX_LOADSIZE]; | 38 | unsigned char *loadbuffer = (unsigned char *)DRAM_START; |
49 | 39 | ||
40 | /* Bootloader version */ | ||
50 | char version[] = APPSVERSION; | 41 | char version[] = APPSVERSION; |
51 | 42 | ||
52 | #define DRAM_START 0x10000000 | ||
53 | |||
54 | int line=0; | ||
55 | char printfbuf[256]; | ||
56 | |||
57 | void reset_screen(void) | ||
58 | { | ||
59 | lcd_clear_display(); | ||
60 | line = 0; | ||
61 | } | ||
62 | |||
63 | void 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 | */ | ||
86 | int 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.*) */ | ||
108 | int 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 | |||
172 | void* main(void) | 43 | void* 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 | |||
243 | void reset_poweroff_timer(void) | ||
244 | { | ||
245 | } | ||
246 | |||
247 | int dbg_ports(void) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | void mpeg_stop(void) | ||
253 | { | ||
254 | } | ||
255 | |||
256 | void usb_acknowledge(void) | 127 | void usb_acknowledge(void) |
257 | { | 128 | { |
258 | } | 129 | } |
@@ -260,7 +131,3 @@ void usb_acknowledge(void) | |||
260 | void usb_wait_for_disconnect(void) | 131 | void usb_wait_for_disconnect(void) |
261 | { | 132 | { |
262 | } | 133 | } |
263 | |||
264 | void 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 | ||