blob: 044c3fc9c0522c03d05192c85756eaa5b3d7b747 [file] [log] [blame]
Hristo Kovachev9dc0e622006-08-11 08:35:27 +00001/***************************************************************************
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 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000015 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
Hristo Kovachev9dc0e622006-08-11 08:35:27 +000019 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
Jonathan Gordonceb1e7a2007-03-22 12:55:51 +000024#include <stdio.h>
25#include <stdlib.h>
Björn Stenbergb69be102008-11-23 22:07:48 +000026
27#include "config.h"
Barry Wardell84b509d2007-01-28 18:42:11 +000028#include "common.h"
Hristo Kovachev9dc0e622006-08-11 08:35:27 +000029#include "cpu.h"
Hristo Kovachev9dc0e622006-08-11 08:35:27 +000030#include "file.h"
Barry Wardell84b509d2007-01-28 18:42:11 +000031#include "system.h"
Michael Sevakis4ea4cdf2014-08-08 02:28:11 -040032#include "../kernel-internal.h"
Barry Wardell84b509d2007-01-28 18:42:11 +000033#include "lcd.h"
34#include "font.h"
Frank Gevaerts2f8a0082008-11-01 16:14:28 +000035#include "storage.h"
Michael Sevakis7d1a47c2013-08-05 22:02:45 -040036#include "file_internal.h"
Barry Wardell1ac260c2008-08-07 11:23:40 +000037#include "adc.h"
Barry Wardell84b509d2007-01-28 18:42:11 +000038#include "button.h"
39#include "disk.h"
Barry Wardell54c73a22007-06-04 13:48:21 +000040#include "crc32-mi4.h"
Marcin Bukat0b296912012-03-04 15:34:29 +010041#include "mi4-loader.h"
42#include "loader_strerror.h"
Barry Wardell14ed3ca2007-03-16 14:28:00 +000043#include <string.h>
Jonathan Gordonfc8e09d2007-11-19 02:07:40 +000044#include "power.h"
Rafaël Carré5d236b22010-05-27 09:41:46 +000045#include "version.h"
Mark Arigob4275d42008-05-21 03:55:17 +000046#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
Barry Wardellf1fead02007-10-14 18:20:23 +000047#include "i2c.h"
48#include "backlight-target.h"
49#endif
Jonathan Gordonceb1e7a2007-03-22 12:55:51 +000050#include "usb.h"
Michael Sevakis71651ca2011-01-15 08:52:59 +000051#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
Björn Stenberg7af22e12007-11-22 22:17:45 +000052#include "usb_drv.h"
Jonathan Gordonceb1e7a2007-03-22 12:55:51 +000053#endif
Thomas Martitze2ccabf2009-09-08 13:57:13 +000054#if defined(SAMSUNG_YH925)
55/* this function (in lcd-yh925.c) resets the screen orientation for the OF
56 * for use with dualbooting */
57void lcd_reset(void);
58#endif
Barry Wardell14ed3ca2007-03-16 14:28:00 +000059
Barry Wardell940091a2008-05-05 12:05:00 +000060/* Show the Rockbox logo - in show_logo.c */
Bertrik Sikken7e3a3f42011-09-08 18:31:15 +000061extern void show_logo(void);
Jonathan Gordonceb1e7a2007-03-22 12:55:51 +000062
63/* Button definitions */
64#if CONFIG_KEYPAD == IRIVER_H10_PAD
65#define BOOTLOADER_BOOT_OF BUTTON_LEFT
66
67#elif CONFIG_KEYPAD == SANSA_E200_PAD
68#define BOOTLOADER_BOOT_OF BUTTON_LEFT
69
Mark Arigodbc6b4e2007-09-06 03:28:58 +000070#elif CONFIG_KEYPAD == SANSA_C200_PAD
71#define BOOTLOADER_BOOT_OF BUTTON_LEFT
72
Mark Arigoe66ddd72008-01-09 07:24:43 +000073#elif CONFIG_KEYPAD == MROBE100_PAD
Robert Kukla6ef63a52008-03-05 00:17:21 +000074#define BOOTLOADER_BOOT_OF BUTTON_POWER
Mark Arigoe66ddd72008-01-09 07:24:43 +000075
Mark Arigob4275d42008-05-21 03:55:17 +000076#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
77#define BOOTLOADER_BOOT_OF BUTTON_VOL_UP
Mark Arigo22e7bf32008-06-27 18:40:25 +000078
79#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
80#define BOOTLOADER_BOOT_OF BUTTON_MENU
81
Mark Arigo6908cc52009-12-25 04:05:01 +000082#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
83#define BOOTLOADER_BOOT_OF BUTTON_VOL_UP
84
Sebastian Leonhardt7f7aee32014-05-22 23:34:52 +020085#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
Sebastian Leonhardte6cd53a2016-01-23 15:54:08 +010086 (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
Mark Arigo758bb3b2009-05-25 21:10:45 +000087#define BOOTLOADER_BOOT_OF BUTTON_LEFT
88
Robert Keevileea149b2009-07-13 21:09:39 +000089#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
90#define BOOTLOADER_BOOT_OF BUTTON_LEFT
91
Szymon Dziok492fafe2010-03-23 21:28:25 +000092#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
93#define BOOTLOADER_BOOT_OF BUTTON_OK
94
Jonathan Gordonceb1e7a2007-03-22 12:55:51 +000095#endif
96
97/* Maximum allowed firmware image size. 10MB is more than enough */
98#define MAX_LOADSIZE (10*1024*1024)
99
100/* A buffer to load the original firmware or Rockbox into */
101unsigned char *loadbuffer = (unsigned char *)DRAM_START;
102
Barry Wardell3de41f52007-03-20 20:45:25 +0000103/* Locations and sizes in hidden partition on Sansa */
Frank Gevaerts19d1cac2008-10-31 21:25:04 +0000104#if (CONFIG_STORAGE & STORAGE_SD)
Barry Wardell3de41f52007-03-20 20:45:25 +0000105#define PPMI_SECTOR_OFFSET 1024
106#define PPMI_SECTORS 1
107#define MI4_HEADER_SECTORS 1
Barry Wardell7cd559d2007-03-20 22:18:35 +0000108#define NUM_PARTITIONS 2
109
110#else
Barry Wardell7cd559d2007-03-20 22:18:35 +0000111#define NUM_PARTITIONS 1
112
113#endif
Barry Wardell3de41f52007-03-20 20:45:25 +0000114
Barry Wardell7e03b0a2007-03-20 22:56:51 +0000115#define MI4_HEADER_SIZE 0x200
116
Barry Wardell3de41f52007-03-20 20:45:25 +0000117/* PPMI header structure */
118struct ppmi_header_t {
119 unsigned char magic[4];
120 uint32_t length;
121 uint32_t pad[126];
122};
123
Frank Gevaerts19d1cac2008-10-31 21:25:04 +0000124#if (CONFIG_STORAGE & STORAGE_SD)
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000125/* Load mi4 firmware from a hidden disk partition */
Jonathan Gordona76947f2007-03-22 12:45:19 +0000126int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
127 unsigned int buffer_size, bool disable_rebuild)
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000128{
129 struct mi4header_t mi4header;
130 struct ppmi_header_t ppmi_header;
131 unsigned long sum;
132
133 /* Read header to find out how long the mi4 file is. */
Frank Gevaerts2dbafc12010-04-03 22:18:16 +0000134 storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET,
135 PPMI_SECTORS, &ppmi_header);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000136
137 /* The first four characters at 0x80000 (sector 1024) should be PPMI*/
138 if( memcmp(ppmi_header.magic, "PPMI", 4) )
139 return EFILE_NOT_FOUND;
140
141 printf("BL mi4 size: %x", ppmi_header.length);
142
143 /* Read mi4 header of the OF */
Frank Gevaerts2dbafc12010-04-03 22:18:16 +0000144 storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
Barry Wardelle293bbb2007-03-17 19:07:20 +0000145 + (ppmi_header.length/512), MI4_HEADER_SECTORS, &mi4header);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000146
147 /* We don't support encrypted mi4 files yet */
Barry Wardellbada0b72007-03-20 12:35:45 +0000148 if( (mi4header.plaintext) != (mi4header.mi4size-MI4_HEADER_SIZE))
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000149 return EINVALID_FORMAT;
150
151 /* MI4 file size */
Barry Wardellbada0b72007-03-20 12:35:45 +0000152 printf("OF mi4 size: %x", mi4header.mi4size);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000153
Barry Wardellbada0b72007-03-20 12:35:45 +0000154 if ((mi4header.mi4size-MI4_HEADER_SIZE) > buffer_size)
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000155 return EFILE_TOO_BIG;
156
157 /* CRC32 */
158 printf("CRC32: %x", mi4header.crc32);
159
160 /* Rockbox model id */
Barry Wardellca8f7bf2007-03-19 11:20:22 +0000161 printf("Model id: %.4s", mi4header.model);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000162
163 /* Read binary type (RBOS, RBBL) */
Barry Wardellca8f7bf2007-03-19 11:20:22 +0000164 printf("Binary type: %.4s", mi4header.type);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000165
166 /* Load firmware */
Frank Gevaerts2dbafc12010-04-03 22:18:16 +0000167 storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
Barry Wardelle293bbb2007-03-17 19:07:20 +0000168 + (ppmi_header.length/512) + MI4_HEADER_SECTORS,
Barry Wardellbada0b72007-03-20 12:35:45 +0000169 (mi4header.mi4size-MI4_HEADER_SIZE)/512, buf);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000170
171 /* Check CRC32 to see if we have a valid file */
Barry Wardelle293bbb2007-03-17 19:07:20 +0000172 sum = chksum_crc32 (buf,mi4header.mi4size-MI4_HEADER_SIZE);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000173
174 printf("Calculated CRC32: %x", sum);
175
176 if(sum != mi4header.crc32)
177 return EBAD_CHKSUM;
178
Barry Wardelld46cf972007-10-20 17:08:41 +0000179#ifdef SANSA_E200
Jonathan Gordona76947f2007-03-22 12:45:19 +0000180 if (disable_rebuild)
181 {
182 char block[512];
Barry Wardelld46cf972007-10-20 17:08:41 +0000183
184 printf("Disabling database rebuild");
185
Frank Gevaerts2dbafc12010-04-03 22:18:16 +0000186 storage_read_sectors(pinfo->start + 0x3c08, 1, block);
Barry Wardelld46cf972007-10-20 17:08:41 +0000187 block[0xe1] = 0;
Frank Gevaerts2dbafc12010-04-03 22:18:16 +0000188 storage_write_sectors(pinfo->start + 0x3c08, 1, block);
Jonathan Gordona76947f2007-03-22 12:45:19 +0000189 }
Barry Wardell8b6bf8f2007-10-20 18:30:41 +0000190#else
191 (void) disable_rebuild;
Barry Wardelld46cf972007-10-20 17:08:41 +0000192#endif
193
Marcin Bukat0b296912012-03-04 15:34:29 +0100194 return mi4header.mi4size-MI4_HEADER_SIZE;
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000195}
Michael Sevakis3a112772011-01-15 08:19:30 +0000196#endif /* (CONFIG_STORAGE & STORAGE_SD) */
197
198#ifdef HAVE_BOOTLOADER_USB_MODE
199/* Return USB_HANDLED if session took place else return USB_EXTRACTED */
200static int handle_usb(int connect_timeout)
201{
202 static struct event_queue q SHAREDBSS_ATTR;
203 struct queue_event ev;
204 int usb = USB_EXTRACTED;
205 long end_tick = 0;
206
207 if (!usb_plugged())
208 return USB_EXTRACTED;
209
210 queue_init(&q, true);
211 usb_init();
212 usb_start_monitoring();
213
Michael Sevakis3a112772011-01-15 08:19:30 +0000214 printf("USB: Connecting");
215
216 if (connect_timeout != TIMEOUT_BLOCK)
217 end_tick = current_tick + connect_timeout;
218
219 while (1)
220 {
221 /* Sleep no longer than 1/2s */
222 queue_wait_w_tmo(&q, &ev, HZ/2);
223
224 if (ev.id == SYS_USB_CONNECTED)
225 {
Michael Sevakisd0178ba2011-01-16 00:21:54 +0000226 /* Switch to verbose mode if not in it so that the status updates
227 * are shown */
228 verbose = true;
Michael Sevakis3a112772011-01-15 08:19:30 +0000229 /* Got the message - wait for disconnect */
230 printf("Bootloader USB mode");
231
232 usb = USB_HANDLED;
233 usb_acknowledge(SYS_USB_CONNECTED_ACK);
234 usb_wait_for_disconnect(&q);
235 break;
236 }
237
238 if (connect_timeout != TIMEOUT_BLOCK &&
239 TIME_AFTER(current_tick, end_tick))
240 {
Michael Sevakisd0178ba2011-01-16 00:21:54 +0000241 /* Timed out waiting for the connect - will happen when connected
242 * to a charger instead of a host port and the charging pin is
243 * the same as the USB pin */
Michael Sevakis3a112772011-01-15 08:19:30 +0000244 printf("USB: Timed out");
245 break;
246 }
247
248 if (!usb_plugged())
249 break; /* Cable pulled */
250 }
251
252 usb_close();
253 queue_delete(&q);
254
255 return usb;
256}
Michael Sevakis71651ca2011-01-15 08:52:59 +0000257#elif (defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
Michael Sevakis5bf25bb2011-01-16 00:35:22 +0000258 || defined (SANSA_VIEW)) && !defined(USE_ROCKBOX_USB)
Michael Sevakis3a112772011-01-15 08:19:30 +0000259/* Return USB_INSERTED if cable present */
260static int handle_usb(int connect_timeout)
261{
262 int usb_retry = 0;
263 int usb = USB_EXTRACTED;
264
265 usb_init();
266 while (usb_drv_powered() && usb_retry < 5 && usb != USB_INSERTED)
267 {
268 usb_retry++;
269 sleep(HZ/4);
270 usb = usb_detect();
271 }
272
273 if (usb != USB_INSERTED)
274 usb = USB_EXTRACTED;
275
276 return usb;
277 (void)connect_timeout;
278}
Michael Sevakis71651ca2011-01-15 08:52:59 +0000279#else
280/* Ignore cable state */
281static int handle_usb(int connect_timeout)
282{
283 return USB_EXTRACTED;
284 (void)connect_timeout;
285}
Michael Sevakis3a112772011-01-15 08:19:30 +0000286#endif /* HAVE_BOOTLOADER_USB_MODE */
287
Barry Wardell1920df32006-08-28 08:11:32 +0000288void* main(void)
289{
Marcin Bukat0b296912012-03-04 15:34:29 +0100290 char filename[MAX_PATH];
Barry Wardell1920df32006-08-28 08:11:32 +0000291 int i;
Barry Wardell23709982007-03-12 22:12:20 +0000292 int btn;
Barry Wardell1920df32006-08-28 08:11:32 +0000293 int rc;
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000294 int num_partitions;
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400295 struct partinfo pinfo;
Michael Sevakis3a112772011-01-15 08:19:30 +0000296#if !(CONFIG_STORAGE & STORAGE_SD)
Mark Arigodbc6b4e2007-09-06 03:28:58 +0000297 char buf[256];
298 unsigned short* identify_info;
Jonathan Gordona76947f2007-03-22 12:45:19 +0000299#endif
Michael Sevakis3a112772011-01-15 08:19:30 +0000300 int usb = USB_EXTRACTED;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000301
Barry Wardell1920df32006-08-28 08:11:32 +0000302 system_init();
303 kernel_init();
Barry Wardell940091a2008-05-05 12:05:00 +0000304
Michael Sevakis3a112772011-01-15 08:19:30 +0000305#ifdef HAVE_BOOTLOADER_USB_MODE
306 /* loader must service interrupts */
307 enable_interrupt(IRQ_FIQ_STATUS);
308#endif
309
Barry Wardell1920df32006-08-28 08:11:32 +0000310 lcd_init();
Barry Wardell940091a2008-05-05 12:05:00 +0000311
Barry Wardell1920df32006-08-28 08:11:32 +0000312 font_init();
Barry Wardell940091a2008-05-05 12:05:00 +0000313 show_logo();
314
Barry Wardell1ac260c2008-08-07 11:23:40 +0000315 adc_init();
Michael Sevakis3a112772011-01-15 08:19:30 +0000316#ifdef HAVE_BOOTLOADER_USB_MODE
317 button_init_device();
318#else
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000319 button_init();
Michael Sevakis3a112772011-01-15 08:19:30 +0000320#endif
Mark Arigob4275d42008-05-21 03:55:17 +0000321#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
Barry Wardellf1fead02007-10-14 18:20:23 +0000322 i2c_init();
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100323 backlight_hw_on();
Barry Wardellf1fead02007-10-14 18:20:23 +0000324#endif
Mark Arigoe66ddd72008-01-09 07:24:43 +0000325
Jonathan Gordonfc8e09d2007-11-19 02:07:40 +0000326 if (button_hold())
327 {
328 verbose = true;
Barry Wardell940091a2008-05-05 12:05:00 +0000329 lcd_clear_display();
Jonathan Gordonfc8e09d2007-11-19 02:07:40 +0000330 printf("Hold switch on");
331 printf("Shutting down...");
332 sleep(HZ);
333 power_off();
334 }
Mark Arigob4275d42008-05-21 03:55:17 +0000335
Barry Wardell23709982007-03-12 22:12:20 +0000336 btn = button_read_device();
Dave Chapmanf0cde2d2008-03-27 00:31:51 +0000337
338 /* Enable bootloader messages if any button is pressed */
Michael Sevakisd0178ba2011-01-16 00:21:54 +0000339#ifdef HAVE_BOOTLOADER_USB_MODE
340 lcd_clear_display();
341 if (btn)
342 verbose = true;
343#else
Barry Wardell940091a2008-05-05 12:05:00 +0000344 if (btn) {
345 lcd_clear_display();
Dave Chapmanf0cde2d2008-03-27 00:31:51 +0000346 verbose = true;
Barry Wardell940091a2008-05-05 12:05:00 +0000347 }
Michael Sevakisd0178ba2011-01-16 00:21:54 +0000348#endif
Dave Chapmanf0cde2d2008-03-27 00:31:51 +0000349
Barry Wardell1920df32006-08-28 08:11:32 +0000350 lcd_setfont(FONT_SYSFIXED);
351
Barry Wardellf4709d02007-01-17 12:20:38 +0000352 printf("Rockbox boot loader");
Michael Sevakis95a4c3a2014-08-28 10:26:45 -0400353 printf("Version: %s", rbversion);
Barry Wardellf4709d02007-01-17 12:20:38 +0000354 printf(MODEL_NAME);
Barry Wardell1920df32006-08-28 08:11:32 +0000355
Frank Gevaerts2f8a0082008-11-01 16:14:28 +0000356 i=storage_init();
Frank Gevaerts19d1cac2008-10-31 21:25:04 +0000357#if !(CONFIG_STORAGE & STORAGE_SD)
Barry Wardell1920df32006-08-28 08:11:32 +0000358 if (i==0) {
Barry Wardell84b509d2007-01-28 18:42:11 +0000359 identify_info=ata_get_identify();
360 /* Show model */
361 for (i=0; i < 20; i++) {
362 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
363 }
364 buf[40]=0;
365 for (i=39; i && buf[i]==' '; i--) {
366 buf[i]=0;
367 }
368 printf(buf);
Barry Wardell1920df32006-08-28 08:11:32 +0000369 } else {
Rafaël Carré1ec82122010-06-23 05:08:36 +0000370 error(EATA, i, true);
Barry Wardell1920df32006-08-28 08:11:32 +0000371 }
Michael Sevakis1167e3c2007-06-30 02:08:27 +0000372#endif
Barry Wardell1920df32006-08-28 08:11:32 +0000373
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400374 filesystem_init();
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000375 num_partitions = disk_mount_all();
376 if (num_partitions<=0)
Barry Wardell1920df32006-08-28 08:11:32 +0000377 {
Rafaël Carré1ec82122010-06-23 05:08:36 +0000378 error(EDISK,num_partitions, true);
Barry Wardell1920df32006-08-28 08:11:32 +0000379 }
380
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000381 /* Just list the first 2 partitions since we don't have any devices yet
382 that have more than that */
Barry Wardell7cd559d2007-03-20 22:18:35 +0000383 for(i=0; i<NUM_PARTITIONS; i++)
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000384 {
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400385 disk_partinfo(i, &pinfo);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000386 printf("Partition %d: 0x%02x %ld MB",
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400387 i, pinfo.type, pinfo.size / 2048);
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000388 }
Barry Wardell1920df32006-08-28 08:11:32 +0000389
Michael Sevakis3a112772011-01-15 08:19:30 +0000390 /* Now that storage is initialized, check for USB connection */
391 if ((btn & BOOTLOADER_BOOT_OF) == 0)
392 {
393 usb_pin_init();
394 usb = handle_usb(HZ*2);
395 if (usb == USB_INSERTED)
396 btn |= BOOTLOADER_BOOT_OF;
397 }
398
Nils Wallménius6ce98bd2009-03-17 20:05:03 +0000399 /* Try loading Rockbox, if that fails, fall back to the OF */
400 if((btn & BOOTLOADER_BOOT_OF) == 0)
401 {
402 printf("Loading Rockbox...");
Marcin Bukat0b296912012-03-04 15:34:29 +0100403 snprintf(filename,sizeof(filename), BOOTDIR "/%s", BOOTFILE);
404
405 rc = load_mi4(loadbuffer, filename, MAX_LOADSIZE);
406 if (rc <= EFILE_EMPTY)
Nils Wallménius6ce98bd2009-03-17 20:05:03 +0000407 {
408 bool old_verbose = verbose;
409 verbose = true;
410 printf("Can't load " BOOTFILE ": ");
Marcin Bukat0b296912012-03-04 15:34:29 +0100411 printf(loader_strerror(rc));
Nils Wallménius6ce98bd2009-03-17 20:05:03 +0000412 verbose = old_verbose;
413 btn |= BOOTLOADER_BOOT_OF;
414 sleep(5*HZ);
415 }
416 else
Michael Sevakis3a112772011-01-15 08:19:30 +0000417 goto main_exit;
Nils Wallménius6ce98bd2009-03-17 20:05:03 +0000418 }
419
Barry Wardella42070d2007-03-15 22:32:58 +0000420 if(btn & BOOTLOADER_BOOT_OF)
Barry Wardell1920df32006-08-28 08:11:32 +0000421 {
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000422 /* Load original mi4 firmware in to a memory buffer called loadbuffer.
423 The rest of the loading is done in crt0.S.
424 1) First try reading from the hidden partition (on Sansa only).
425 2) Next try a decrypted mi4 file in /System/OF.mi4
Thomas Martitze2ccabf2009-09-08 13:57:13 +0000426 3) Finally, try a raw firmware binary in /System/OF.bin. It should be
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000427 a mi4 firmware decrypted and header stripped using mi4code.
Barry Wardell84b509d2007-01-28 18:42:11 +0000428 */
Barry Wardellf4709d02007-01-17 12:20:38 +0000429 printf("Loading original firmware...");
Barry Wardella91a35b2007-03-16 14:36:14 +0000430
Frank Gevaerts19d1cac2008-10-31 21:25:04 +0000431#if (CONFIG_STORAGE & STORAGE_SD)
Barry Wardella91a35b2007-03-16 14:36:14 +0000432 /* First try a (hidden) firmware partition */
433 printf("Trying firmware partition");
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400434 disk_partinfo(1, &pinfo);
435 if(pinfo.type == PARTITION_TYPE_OS2_HIDDEN_C_DRIVE)
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000436 {
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400437 rc = load_mi4_part(loadbuffer, &pinfo, MAX_LOADSIZE,
Michael Sevakis71651ca2011-01-15 08:52:59 +0000438 usb == USB_INSERTED);
Marcin Bukat0b296912012-03-04 15:34:29 +0100439 if (rc <= EFILE_EMPTY) {
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000440 printf("Can't load from partition");
Marcin Bukat0b296912012-03-04 15:34:29 +0100441 printf(loader_strerror(rc));
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000442 } else {
Michael Sevakis3a112772011-01-15 08:19:30 +0000443 goto main_exit;
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000444 }
445 } else {
446 printf("No hidden partition found.");
447 }
Barry Wardella91a35b2007-03-16 14:36:14 +0000448#endif
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000449
Michael Sevakis0afad892011-01-09 19:31:41 +0000450#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) || defined(PHILIPS_SA9200)
Mark Arigo3482a552009-01-10 03:21:07 +0000451 printf("Trying /System/OF.ebn");
452 rc=load_mi4(loadbuffer, "/System/OF.ebn", MAX_LOADSIZE);
Marcin Bukat0b296912012-03-04 15:34:29 +0100453 if (rc <= EFILE_EMPTY) {
Mark Arigo3482a552009-01-10 03:21:07 +0000454 printf("Can't load /System/OF.ebn");
Marcin Bukat0b296912012-03-04 15:34:29 +0100455 printf(loader_strerror(rc));
Mark Arigo3482a552009-01-10 03:21:07 +0000456 } else {
Michael Sevakis3a112772011-01-15 08:19:30 +0000457 goto main_exit;
Mark Arigo3482a552009-01-10 03:21:07 +0000458 }
459#endif
460
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000461 printf("Trying /System/OF.mi4");
462 rc=load_mi4(loadbuffer, "/System/OF.mi4", MAX_LOADSIZE);
Marcin Bukat0b296912012-03-04 15:34:29 +0100463 if (rc <= EFILE_EMPTY) {
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000464 printf("Can't load /System/OF.mi4");
Marcin Bukat0b296912012-03-04 15:34:29 +0100465 printf(loader_strerror(rc));
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000466 } else {
Thomas Martitze2ccabf2009-09-08 13:57:13 +0000467#if defined(SAMSUNG_YH925)
468 lcd_reset();
469#endif
Michael Sevakis3a112772011-01-15 08:19:30 +0000470 goto main_exit;
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000471 }
472
473 printf("Trying /System/OF.bin");
Barry Wardell84b509d2007-01-28 18:42:11 +0000474 rc=load_raw_firmware(loadbuffer, "/System/OF.bin", MAX_LOADSIZE);
Marcin Bukat0b296912012-03-04 15:34:29 +0100475 if (rc <= EFILE_EMPTY) {
Barry Wardell23709982007-03-12 22:12:20 +0000476 printf("Can't load /System/OF.bin");
Marcin Bukat0b296912012-03-04 15:34:29 +0100477 printf(loader_strerror(rc));
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000478 } else {
Thomas Martitze2ccabf2009-09-08 13:57:13 +0000479#if defined(SAMSUNG_YH925)
480 lcd_reset();
481#endif
Michael Sevakis3a112772011-01-15 08:19:30 +0000482 goto main_exit;
Barry Wardell84b509d2007-01-28 18:42:11 +0000483 }
Barry Wardell0c1a3042007-03-20 10:36:26 +0000484
Rafaël Carré1ec82122010-06-23 05:08:36 +0000485 error(0, 0, true);
Barry Wardell1920df32006-08-28 08:11:32 +0000486 }
Michael Sevakis3a112772011-01-15 08:19:30 +0000487
488main_exit:
489#ifdef HAVE_BOOTLOADER_USB_MODE
490 storage_close();
491 system_prepare_fw_start();
492#endif
493
Barry Wardell84b509d2007-01-28 18:42:11 +0000494 return (void*)loadbuffer;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000495}