create an UnZip derived class for zip file extraction to allow showing progress while...
[Rockbox.git] / bootloader / common.c
blobe6b8f5a7d2ee6d4d199d0d3f5f141d0af0195dfd
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
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 ****************************************************************************/
19 #include "lcd.h"
20 #include "lcd-remote.h"
21 #include "font.h"
22 #include "system.h"
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdbool.h>
26 #include "cpu.h"
27 #include "common.h"
28 #include "power.h"
29 #include "kernel.h"
31 /* TODO: Other bootloaders need to be adjusted to set this variable to true
32 on a button press - currently only the ipod, H10 and Sansa versions do. */
33 #if defined(IPOD_ARCH) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) \
34 || defined(SANSA_E200) || defined(SANSA_C200) || defined(GIGABEAT_F)
35 bool verbose = false;
36 #else
37 bool verbose = true;
38 #endif
40 int line = 0;
41 #ifdef HAVE_REMOTE_LCD
42 int remote_line = 0;
43 #endif
45 char printfbuf[256];
47 void reset_screen(void)
49 lcd_clear_display();
50 line = 0;
51 #ifdef HAVE_REMOTE_LCD
52 lcd_remote_clear_display();
53 remote_line = 0;
54 #endif
57 void printf(const char *format, ...)
59 int len;
60 unsigned char *ptr;
61 va_list ap;
62 va_start(ap, format);
64 ptr = printfbuf;
65 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
66 va_end(ap);
68 lcd_puts(0, line++, ptr);
69 if (verbose)
70 lcd_update();
71 if(line >= LCD_HEIGHT/SYSFONT_HEIGHT)
72 line = 0;
73 #ifdef HAVE_REMOTE_LCD
74 lcd_remote_puts(0, remote_line++, ptr);
75 if (verbose)
76 lcd_remote_update();
77 if(remote_line >= LCD_REMOTE_HEIGHT/SYSFONT_HEIGHT)
78 remote_line = 0;
79 #endif
82 char *strerror(int error)
84 switch(error)
86 case EOK:
87 return "OK";
88 case EFILE_NOT_FOUND:
89 return "File not found";
90 case EREAD_CHKSUM_FAILED:
91 return "Read failed (chksum)";
92 case EREAD_MODEL_FAILED:
93 return "Read failed (model)";
94 case EREAD_IMAGE_FAILED:
95 return "Read failed (image)";
96 case EBAD_CHKSUM:
97 return "Bad checksum";
98 case EFILE_TOO_BIG:
99 return "File too big";
100 case EINVALID_FORMAT:
101 return "Invalid file format";
102 default:
103 return "Unknown";
107 void error(int errortype, int error)
109 switch(errortype)
111 case EATA:
112 printf("ATA error: %d", error);
113 break;
115 case EDISK:
116 printf("No partition found");
117 break;
119 case EBOOTFILE:
120 printf(strerror(error));
121 break;
124 lcd_update();
125 sleep(5*HZ);
126 power_off();
129 /* Load firmware image in a format created by tools/scramble */
130 int load_firmware(unsigned char* buf, char* firmware, int buffer_size)
132 int fd;
133 int rc;
134 int len;
135 unsigned long chksum;
136 char model[5];
137 unsigned long sum;
138 int i;
139 char filename[MAX_PATH];
141 snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware);
142 fd = open(filename, O_RDONLY);
143 if(fd < 0)
145 snprintf(filename,sizeof(filename),"/%s",firmware);
146 fd = open(filename, O_RDONLY);
147 if(fd < 0)
148 return EFILE_NOT_FOUND;
151 len = filesize(fd) - 8;
153 printf("Length: %x", len);
155 if (len > buffer_size)
156 return EFILE_TOO_BIG;
158 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
160 rc = read(fd, &chksum, 4);
161 chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
162 if(rc < 4)
163 return EREAD_CHKSUM_FAILED;
165 printf("Checksum: %x", chksum);
167 rc = read(fd, model, 4);
168 if(rc < 4)
169 return EREAD_MODEL_FAILED;
171 model[4] = 0;
173 printf("Model name: %s", model);
174 printf("Loading %s", firmware);
176 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
178 rc = read(fd, buf, len);
179 if(rc < len)
180 return EREAD_IMAGE_FAILED;
182 close(fd);
184 sum = MODEL_NUMBER;
186 for(i = 0;i < len;i++) {
187 sum += buf[i];
190 printf("Sum: %x", sum);
192 if(sum != chksum)
193 return EBAD_CHKSUM;
195 return EOK;
198 /* Load raw binary image. */
199 int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size)
201 int fd;
202 int rc;
203 int len;
204 char filename[MAX_PATH];
206 snprintf(filename,sizeof(filename),"%s",firmware);
207 fd = open(filename, O_RDONLY);
208 if(fd < 0)
210 return EFILE_NOT_FOUND;
213 len = filesize(fd);
215 if (len > buffer_size)
216 return EFILE_TOO_BIG;
218 rc = read(fd, buf, len);
219 if(rc < len)
220 return EREAD_IMAGE_FAILED;
222 close(fd);
223 return len;
226 /* These functions are present in the firmware library, but we reimplement
227 them here because the originals do a lot more than we want */
228 void reset_poweroff_timer(void)
232 int dbg_ports(void)
234 return 0;
237 void mpeg_stop(void)
241 void sys_poweroff(void)