1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Greg White
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
31 #include "usb-target.h"
34 #define TAR_HEADER_SIZE 157
36 const char version
[] = APPSVERSION
;
37 /* Where files sent via MTP are stored */
38 static const char basedir
[] = "/Content/0b00/00/";
39 /* Can use memory after vector table up to 0x01f00000 */
40 static char * const tarbuf
= (char *)0x00000040;
41 static const size_t tarbuf_size
= 0x01f00000 - 0x00000040;
42 /* Queue to get notifications when in USB mode */
43 static struct event_queue usb_wait_queue
;
45 static void show_splash(int timeout
, const char *msg
)
47 lcd_putsxy( (LCD_WIDTH
- (SYSFONT_WIDTH
* strlen(msg
))) / 2,
48 (LCD_HEIGHT
- SYSFONT_HEIGHT
) / 2, msg
);
54 static void untar(int tar_fd
)
56 char header
[TAR_HEADER_SIZE
];
61 size_t size
= filesize(tar_fd
);
63 if (size
> tarbuf_size
) {
64 printf("tar file too large"); /* Paranoid but proper */
68 ret
= read(tar_fd
, tarbuf
, filesize(tar_fd
));
70 printf("couldn't read tar file (%d)", ret
);
77 memcpy(header
, ptr
, TAR_HEADER_SIZE
);
79 if (*header
== '\0') /* Check for EOF */
82 /* Parse the size field */
84 for (i
= 124 ; i
< 124 + 11 ; i
++) {
85 size
= (8 * size
) + header
[i
] - '0';
88 /* Skip rest of header */
91 /* Make the path absolute */
95 if (header
[156] == '0') /* file */
102 printf("failed to create file (%d)", fd
);
106 wc
= write(fd
, ptr
, size
);
109 printf("write failed (%d)", wc
);
114 ptr
+= (size
+ TAR_CHUNK
-1) & (~(TAR_CHUNK
-1));
116 else if (header
[156] == '5') /* directory */
120 /* Remove the trailing slash */
121 if (path
[strlen(path
) - 1] == '/')
122 path
[strlen(path
) - 1] = '\0';
126 if (ret
< 0 && ret
!= -4)
128 printf("failed to create dir (%d)", ret
);
140 /* Flush and invalidate all caches (because vectors were written) */
144 printf("Gigabeat S Rockbox Bootloader v.00000013");
147 printf("kernel init done");
150 enable_interrupt(IRQ_FIQ_STATUS
);
158 printf("ata init done");
161 printf("disk init done");
163 rc
= disk_mount_all();
169 /* Look for a tar file */
170 struct dirent_uncached
* entry
;
173 dir
= opendir_uncached(basedir
);
174 while ((entry
= readdir_uncached(dir
)))
176 if (*entry
->d_name
!= '.')
178 snprintf(buf
, sizeof(buf
), "%s%s", basedir
, entry
->d_name
);
179 fd
= open(buf
, O_RDONLY
);
182 /* Check whether the file is a rockbox binary. */
183 lseek(fd
, 4, SEEK_SET
);
184 rc
= read(fd
, model
, 4);
188 if (strcmp(model
, "gigs") == 0)
190 printf("Found rockbox binary. Moving...");
192 remove("/.rockbox/rockbox.gigabeat");
193 int ret
= rename(buf
, "/.rockbox/rockbox.gigabeat");
194 printf("returned %d", ret
);
200 /* Check whether the file is a tar file. */
201 lseek(fd
, 257, SEEK_SET
);
202 rc
= read(fd
, tarstring
, 5);
206 if (strcmp(tarstring
, "ustar") == 0)
208 printf("Found tar file. Unarchiving...");
209 lseek(fd
, 0, SEEK_SET
);
212 printf("Removing tar file");
225 struct queue_event ev
;
226 queue_init(&usb_wait_queue
, true);
228 /* Start the USB driver */
230 usb_start_monitoring();
232 /* Wait for threads to connect or cable is pulled */
234 show_splash(0, "Waiting for USB");
238 queue_wait_w_tmo(&usb_wait_queue
, &ev
, HZ
/2);
240 if (ev
.id
== SYS_USB_CONNECTED
)
244 break; /* Cable pulled */
247 if (ev
.id
== SYS_USB_CONNECTED
)
249 /* Got the message - wait for disconnect */
251 show_splash(0, "Bootloader USB mode");
253 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
254 usb_wait_for_disconnect(&usb_wait_queue
);
257 /* No more monitoring */
258 usb_stop_monitoring();
264 /* Bang on the controller */
268 unsigned char *loadbuffer
= (unsigned char *)0x0;
269 int buffer_size
= 31*1024*1024;
271 rc
= load_firmware(loadbuffer
, "/.rockbox/rockbox.gigabeat", buffer_size
);
273 error(EBOOTFILE
, rc
);
275 system_prepare_fw_start();
280 asm volatile ("bx %0": : "r"(loadbuffer
));