diff options
Diffstat (limited to 'bootloader/main-pp.c')
-rw-r--r-- | bootloader/main-pp.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c new file mode 100644 index 0000000000..a533cc7044 --- /dev/null +++ b/bootloader/main-pp.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing | ||
13 | * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include "config.h" | ||
23 | |||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include "cpu.h" | ||
28 | #include "system.h" | ||
29 | #include "lcd.h" | ||
30 | #include "kernel.h" | ||
31 | #include "thread.h" | ||
32 | #include "ata.h" | ||
33 | #include "fat.h" | ||
34 | #include "disk.h" | ||
35 | #include "font.h" | ||
36 | #include "adc.h" | ||
37 | #include "backlight.h" | ||
38 | #include "button.h" | ||
39 | #include "panic.h" | ||
40 | #include "power.h" | ||
41 | #include "file.h" | ||
42 | |||
43 | /* Size of the buffer to store the loaded firmware image */ | ||
44 | #define MAX_LOADSIZE (10*1024*1024) | ||
45 | |||
46 | /* A buffer to load the iriver firmware or Rockbox into */ | ||
47 | unsigned char loadbuffer[MAX_LOADSIZE]; | ||
48 | |||
49 | char version[] = APPSVERSION; | ||
50 | |||
51 | #define DRAM_START 0x10000000 | ||
52 | |||
53 | int line=0; | ||
54 | |||
55 | /* Load original mi4 firmware. This function expects a file called | ||
56 | "/System/OF.bin" on the player. It should be a mi4 firmware decrypted | ||
57 | and header stripped using mi4code. It reads the file in to a memory | ||
58 | buffer called buf. The rest of the loading is done in main() and crt0.S | ||
59 | */ | ||
60 | int load_original_firmware(unsigned char* buf) | ||
61 | { | ||
62 | int fd; | ||
63 | int rc; | ||
64 | int len; | ||
65 | |||
66 | fd = open("/System/OF.bin", O_RDONLY); | ||
67 | |||
68 | len = filesize(fd); | ||
69 | |||
70 | if (len > MAX_LOADSIZE) | ||
71 | return -6; | ||
72 | |||
73 | rc = read(fd, buf, len); | ||
74 | if(rc < len) | ||
75 | return -4; | ||
76 | |||
77 | close(fd); | ||
78 | return len; | ||
79 | } | ||
80 | |||
81 | /* Load Rockbox firmware (rockbox.*) */ | ||
82 | int load_rockbox(unsigned char* buf) | ||
83 | { | ||
84 | int fd; | ||
85 | int rc; | ||
86 | int len; | ||
87 | unsigned long chksum; | ||
88 | char model[5]; | ||
89 | unsigned long sum; | ||
90 | int i; | ||
91 | char str[80]; | ||
92 | |||
93 | fd = open("/.rockbox/" BOOTFILE, O_RDONLY); | ||
94 | if(fd < 0) | ||
95 | { | ||
96 | fd = open("/" BOOTFILE, O_RDONLY); | ||
97 | if(fd < 0) | ||
98 | return -1; | ||
99 | } | ||
100 | |||
101 | len = filesize(fd) - 8; | ||
102 | |||
103 | snprintf(str, sizeof(str), "Length: %x", len); | ||
104 | lcd_puts(0, line++ ,str); | ||
105 | lcd_update(); | ||
106 | |||
107 | if (len > MAX_LOADSIZE) | ||
108 | return -6; | ||
109 | |||
110 | lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); | ||
111 | |||
112 | rc = read(fd, &chksum, 4); | ||
113 | chksum=betoh32(chksum); /* Rockbox checksums are big-endian */ | ||
114 | if(rc < 4) | ||
115 | return -2; | ||
116 | |||
117 | snprintf(str, sizeof(str), "Checksum: %x", chksum); | ||
118 | lcd_puts(0, line++ ,str); | ||
119 | lcd_update(); | ||
120 | |||
121 | rc = read(fd, model, 4); | ||
122 | if(rc < 4) | ||
123 | return -3; | ||
124 | |||
125 | model[4] = 0; | ||
126 | |||
127 | snprintf(str, sizeof(str), "Model name: %s", model); | ||
128 | lcd_puts(0, line++ ,str); | ||
129 | lcd_update(); | ||
130 | |||
131 | lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); | ||
132 | |||
133 | rc = read(fd, buf, len); | ||
134 | if(rc < len) | ||
135 | return -4; | ||
136 | |||
137 | close(fd); | ||
138 | |||
139 | sum = MODEL_NUMBER; | ||
140 | |||
141 | for(i = 0;i < len;i++) { | ||
142 | sum += buf[i]; | ||
143 | } | ||
144 | |||
145 | snprintf(str, sizeof(str), "Sum: %x", sum); | ||
146 | lcd_puts(0, line++ ,str); | ||
147 | lcd_update(); | ||
148 | |||
149 | if(sum != chksum) | ||
150 | return -5; | ||
151 | |||
152 | return len; | ||
153 | } | ||
154 | |||
155 | void* main(void) | ||
156 | { | ||
157 | char buf[256]; | ||
158 | int i; | ||
159 | int rc; | ||
160 | unsigned short* identify_info; | ||
161 | struct partinfo* pinfo; | ||
162 | |||
163 | system_init(); | ||
164 | kernel_init(); | ||
165 | lcd_init(); | ||
166 | font_init(); | ||
167 | button_init(); | ||
168 | |||
169 | line=0; | ||
170 | |||
171 | lcd_setfont(FONT_SYSFIXED); | ||
172 | |||
173 | lcd_puts(0, line++, "Rockbox boot loader"); | ||
174 | snprintf(buf, sizeof(buf), "Version: 20%s", version); | ||
175 | lcd_puts(0, line++, buf); | ||
176 | snprintf(buf, sizeof(buf), MODEL_NAME); | ||
177 | lcd_puts(0, line++, buf); | ||
178 | lcd_update(); | ||
179 | |||
180 | i=ata_init(); | ||
181 | if (i==0) { | ||
182 | identify_info=ata_get_identify(); | ||
183 | /* Show model */ | ||
184 | for (i=0; i < 20; i++) { | ||
185 | ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); | ||
186 | } | ||
187 | buf[40]=0; | ||
188 | for (i=39; i && buf[i]==' '; i--) { | ||
189 | buf[i]=0; | ||
190 | } | ||
191 | lcd_puts(0, line++, buf); | ||
192 | lcd_update(); | ||
193 | } else { | ||
194 | snprintf(buf, sizeof(buf), "ATA: %d", i); | ||
195 | lcd_puts(0, line++, buf); | ||
196 | lcd_update(); | ||
197 | } | ||
198 | |||
199 | disk_init(); | ||
200 | rc = disk_mount_all(); | ||
201 | if (rc<=0) | ||
202 | { | ||
203 | lcd_puts(0, line++, "No partition found"); | ||
204 | lcd_update(); | ||
205 | } | ||
206 | |||
207 | pinfo = disk_partinfo(0); | ||
208 | snprintf(buf, sizeof(buf), "Partition 0: 0x%02x %ld MB", | ||
209 | pinfo->type, pinfo->size / 2048); | ||
210 | lcd_puts(0, line++, buf); | ||
211 | lcd_update(); | ||
212 | |||
213 | i=button_read_device(); | ||
214 | if(i==BUTTON_LEFT) | ||
215 | { | ||
216 | lcd_puts(0, line++, "Loading original firmware..."); | ||
217 | lcd_update(); | ||
218 | rc=load_original_firmware(loadbuffer); | ||
219 | } else { | ||
220 | lcd_puts(0, line++, "Loading Rockbox..."); | ||
221 | lcd_update(); | ||
222 | rc=load_rockbox(loadbuffer); | ||
223 | } | ||
224 | |||
225 | if (rc < 0) { | ||
226 | snprintf(buf, sizeof(buf), "Rockbox error: %d",rc); | ||
227 | lcd_puts(0, line++, buf); | ||
228 | lcd_update(); | ||
229 | while(1) {} | ||
230 | } | ||
231 | |||
232 | memcpy((void*)DRAM_START,loadbuffer,rc); | ||
233 | |||
234 | return (void*)DRAM_START; | ||
235 | } | ||
236 | |||
237 | /* These functions are present in the firmware library, but we reimplement | ||
238 | them here because the originals do a lot more than we want */ | ||
239 | |||
240 | void reset_poweroff_timer(void) | ||
241 | { | ||
242 | } | ||
243 | |||
244 | int dbg_ports(void) | ||
245 | { | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | void mpeg_stop(void) | ||
250 | { | ||
251 | } | ||
252 | |||
253 | void usb_acknowledge(void) | ||
254 | { | ||
255 | } | ||
256 | |||
257 | void usb_wait_for_disconnect(void) | ||
258 | { | ||
259 | } | ||
260 | |||
261 | void sys_poweroff(void) | ||
262 | { | ||
263 | } | ||