diff options
Diffstat (limited to 'bootloader/h10.c')
-rw-r--r-- | bootloader/h10.c | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/bootloader/h10.c b/bootloader/h10.c new file mode 100644 index 0000000000..e80e28fe5b --- /dev/null +++ b/bootloader/h10.c | |||
@@ -0,0 +1,262 @@ | |||
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 Rockbox/iriver image */ | ||
44 | #define MAX_LOADSIZE (5*1024*1024) | ||
45 | |||
46 | /* This is identical to the function used in the iPod bootloader */ | ||
47 | static void memmove16(void *dest, const void *src, unsigned count) | ||
48 | { | ||
49 | struct bufstr { | ||
50 | unsigned _buf[4]; | ||
51 | } *d, *s; | ||
52 | |||
53 | if (src >= dest) { | ||
54 | count = (count + 15) >> 4; | ||
55 | d = (struct bufstr *) dest; | ||
56 | s = (struct bufstr *) src; | ||
57 | while (count--) | ||
58 | *d++ = *s++; | ||
59 | } else { | ||
60 | count = (count + 15) >> 4; | ||
61 | d = (struct bufstr *)(dest + (count <<4)); | ||
62 | s = (struct bufstr *)(src + (count <<4)); | ||
63 | while (count--) | ||
64 | *--d = *--s; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | |||
69 | /* Load original iriver firmware. This function expects a file called "H10_20GC.mi4" in | ||
70 | the root directory of the player. It should be decrypted and have the header stripped | ||
71 | using mi4code. It reads the file in to a memory buffer called buf. The rest of the | ||
72 | loading is done in main() | ||
73 | */ | ||
74 | int load_iriver(unsigned char* buf) | ||
75 | { | ||
76 | int fd; | ||
77 | int rc; | ||
78 | int len; | ||
79 | |||
80 | fd = open("/H10_20GC.mi4", O_RDONLY); | ||
81 | |||
82 | len = filesize(fd); | ||
83 | rc = read(fd, buf, len); | ||
84 | if(rc < len) | ||
85 | return -4; | ||
86 | |||
87 | close(fd); | ||
88 | return len; | ||
89 | } | ||
90 | |||
91 | /* A buffer to load the iriver firmware or Rockbox into */ | ||
92 | unsigned char loadbuffer[MAX_LOADSIZE]; | ||
93 | |||
94 | void main(void) | ||
95 | { | ||
96 | /* Attempt to load original iriver firmware. Successfully starts loading the iriver | ||
97 | firmware but then locks up once the "System Initialising" screen is displayed. | ||
98 | |||
99 | The iriver firmware was decrypted and the header removed. It was then appended to | ||
100 | the end of bootloader.bin and an mi4 file was created from the resulting file. | ||
101 | |||
102 | The original firmware starts at 0xd800 in the file and is of length 0x47da00. | ||
103 | |||
104 | The whole file (bootloader.bin + decrypted mi4) are loaded to memory by the | ||
105 | original iriver bootloader on startup. This copies the mi4 part to the start | ||
106 | of DRAM and passes execution to there. | ||
107 | |||
108 | memmove16((void*)DRAMORIG, (void*)(DRAMORIG + 0xd800), 0x47da00); | ||
109 | asm volatile( | ||
110 | "mov r0, #" SC(DRAMORIG) "\n" | ||
111 | "mov pc, r0 \n" | ||
112 | ); | ||
113 | */ | ||
114 | |||
115 | int i; | ||
116 | int rc; | ||
117 | int btn; | ||
118 | |||
119 | i=ata_init(); | ||
120 | disk_init(); | ||
121 | rc = disk_mount_all(); | ||
122 | |||
123 | /* Load original iriver firmware. Uses load_iriver(buf) to load the decrypted mi4 file from | ||
124 | disk to DRAM. This then copies that part of DRAM to the start of DRAM and passes | ||
125 | execution to there. | ||
126 | |||
127 | rc=load_iriver(loadbuffer); | ||
128 | memcpy((void*)DRAMORIG,loadbuffer,rc); | ||
129 | asm volatile( | ||
130 | "mov r0, #" SC(DRAMORIG) "\n" | ||
131 | "mov pc, r0 \n" | ||
132 | );*/ | ||
133 | |||
134 | |||
135 | /* This assumes that /test.txt exists */ | ||
136 | int fd; | ||
137 | char buffer[24]; | ||
138 | fd=open("/test.txt",O_RDWR); | ||
139 | |||
140 | |||
141 | /* WARNING: Running this code on the H10 caused permanent damage to my H10's hdd | ||
142 | I strongly recommend against trying it. | ||
143 | |||
144 | for(i=0;i<100;i++){ | ||
145 | btn = button_read_device(); | ||
146 | switch(btn){ | ||
147 | case BUTTON_LEFT: | ||
148 | snprintf(buffer, sizeof(buffer), "Left"); | ||
149 | write(fd,buffer,sizeof(buffer)); | ||
150 | break; | ||
151 | case BUTTON_RIGHT: | ||
152 | break; | ||
153 | case BUTTON_REW: | ||
154 | break; | ||
155 | case BUTTON_FF: | ||
156 | break; | ||
157 | case BUTTON_PLAY: | ||
158 | break; | ||
159 | default: | ||
160 | break; | ||
161 | } | ||
162 | |||
163 | |||
164 | } | ||
165 | */ | ||
166 | |||
167 | |||
168 | |||
169 | /* Investigate gpio | ||
170 | |||
171 | unsigned int gpio_a, gpio_b, gpio_c, gpio_d; | ||
172 | unsigned int gpio_e, gpio_f, gpio_g, gpio_h; | ||
173 | unsigned int gpio_i, gpio_j, gpio_k, gpio_l; | ||
174 | |||
175 | gpio_a = GPIOA_INPUT_VAL; | ||
176 | gpio_b = GPIOB_INPUT_VAL; | ||
177 | gpio_c = GPIOC_INPUT_VAL; | ||
178 | |||
179 | gpio_g = GPIOG_INPUT_VAL; | ||
180 | gpio_h = GPIOH_INPUT_VAL; | ||
181 | gpio_i = GPIOI_INPUT_VAL; | ||
182 | |||
183 | snprintf(buffer, sizeof(buffer), "GPIO_A: %02x GPIO_G: %02x\n", gpio_a, gpio_g); | ||
184 | write(fd,buffer,sizeof(buffer)); | ||
185 | snprintf(buffer, sizeof(buffer), "GPIO_B: %02x GPIO_H: %02x\n", gpio_b, gpio_h); | ||
186 | write(fd,buffer,sizeof(buffer)); | ||
187 | snprintf(buffer, sizeof(buffer), "GPIO_C: %02x GPIO_I: %02x\n", gpio_c, gpio_i); | ||
188 | write(fd,buffer,sizeof(buffer)); | ||
189 | |||
190 | gpio_d = GPIOD_INPUT_VAL; | ||
191 | gpio_e = GPIOE_INPUT_VAL; | ||
192 | gpio_f = GPIOF_INPUT_VAL; | ||
193 | |||
194 | gpio_j = GPIOJ_INPUT_VAL; | ||
195 | gpio_k = GPIOK_INPUT_VAL; | ||
196 | gpio_l = GPIOL_INPUT_VAL; | ||
197 | |||
198 | snprintf(buffer, sizeof(buffer), "GPIO_D: %02x GPIO_J: %02x\n", gpio_d, gpio_j); | ||
199 | write(fd,buffer,sizeof(buffer)); | ||
200 | snprintf(buffer, sizeof(buffer), "GPIO_E: %02x GPIO_K: %02x\n", gpio_e, gpio_k); | ||
201 | write(fd,buffer,sizeof(buffer)); | ||
202 | snprintf(buffer, sizeof(buffer), "GPIO_F: %02x GPIO_L: %02x\n", gpio_f, gpio_l); | ||
203 | write(fd,buffer,sizeof(buffer)); | ||
204 | */ | ||
205 | |||
206 | |||
207 | |||
208 | /* Detect the scroller being touched | ||
209 | |||
210 | int j = 0; | ||
211 | for(j=0;j<1000;j++){ | ||
212 | if(gpio_c!=0xF7){ | ||
213 | snprintf(buffer, sizeof(buffer), "GPIO_C: %02x\n", gpio_c); | ||
214 | write(fd,buffer,sizeof(buffer)); | ||
215 | } | ||
216 | if(gpio_d!=0xDD){ | ||
217 | snprintf(buffer, sizeof(buffer), "GPIO_D: %02x\n", gpio_d); | ||
218 | write(fd,buffer,sizeof(buffer)); | ||
219 | } | ||
220 | }*/ | ||
221 | |||
222 | |||
223 | /* Apparently necessary for the data to be actually written to file */ | ||
224 | fsync(fd); | ||
225 | udelay(1000000); | ||
226 | |||
227 | /* This causes the device to shut off instantly | ||
228 | |||
229 | GPIOF_OUTPUT_VAL = 0; | ||
230 | */ | ||
231 | |||
232 | close(fd); | ||
233 | udelay(1000000); | ||
234 | } | ||
235 | |||
236 | /* These functions are present in the firmware library, but we reimplement | ||
237 | them here because the originals do a lot more than we want */ | ||
238 | |||
239 | void reset_poweroff_timer(void) | ||
240 | { | ||
241 | } | ||
242 | |||
243 | int dbg_ports(void) | ||
244 | { | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | void mpeg_stop(void) | ||
249 | { | ||
250 | } | ||
251 | |||
252 | void usb_acknowledge(void) | ||
253 | { | ||
254 | } | ||
255 | |||
256 | void usb_wait_for_disconnect(void) | ||
257 | { | ||
258 | } | ||
259 | |||
260 | void sys_poweroff(void) | ||
261 | { | ||
262 | } | ||