diff options
Diffstat (limited to 'bootloader/main-pp.c')
-rw-r--r-- | bootloader/main-pp.c | 225 |
1 files changed, 46 insertions, 179 deletions
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 | } | ||