blob: d85a2281672f88d8352e4e2aebbe96ca71378396 [file] [log] [blame]
Frank Gevaerts2b9e9442011-09-02 21:34:28 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main-e200r-installer.c 15599 2007-11-12 18:49:53Z amiconn $
9 *
10 * Copyright (C) 2011 by Frank Gevaerts
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include "common.h"
23#include "cpu.h"
24#include "file.h"
25#include "system.h"
Michael Sevakis4ea4cdf2014-08-08 02:28:11 -040026#include "../kernel-internal.h"
Frank Gevaerts2b9e9442011-09-02 21:34:28 +000027#include "lcd.h"
28#include "font.h"
29#include "storage.h"
30#include "button.h"
31#include "disk.h"
Frank Gevaerts2b9e9442011-09-02 21:34:28 +000032#include <string.h>
33#include "i2c.h"
34#include "backlight-target.h"
35#include "power.h"
36
37unsigned char zero[1024*64];
38unsigned char nonzero[1024*64];
39unsigned char scratch[1024*64];
40struct storage_info info;
41
42int format_partition(int start, int size);
43
44#define SPT 63
45#define HPC 255
46
47int c(int lba)
48{
49 return lba/(SPT * HPC);
50}
51int h(int lba)
52{
53 return (lba/SPT)%HPC;
54}
55int s(int lba)
56{
57 return (lba%SPT) + 1;
58}
59
60int write_mbr(int datastart,int datasize, int firmwarestart, int firmwaresize)
61{
62 unsigned char mbr[512];
63 memset(mbr,0,512);
64 mbr[446]=0x80; /* flags */
65 mbr[447]=h(datastart); /* chs1[0] (h) */
66 mbr[448]=s(datastart); /* chs1[1] (s) */
67 mbr[449]=c(datastart); /* chs1[2] (c) */
68 mbr[450]=0x0b; /* type */
69 mbr[451]=h(datastart+datasize-1); /* chs2[0] (h) */
70 mbr[452]=s(datastart+datasize-1); /* chs2[1] (s) */
71 mbr[453]=c(datastart+datasize-1); /* chs2[2] (c) */
72 mbr[454]=(datastart&0x000000ff); /* lba[0] */
73 mbr[455]=(datastart&0x0000ff00) >>8; /* lba[1] */
74 mbr[456]=(datastart&0x00ff0000) >>16; /* lba[2] */
75 mbr[457]=(datastart&0xff000000) >>24; /* lba[3] */
76 mbr[458]=(datasize&0x000000ff); /* size[0] */
77 mbr[459]=(datasize&0x0000ff00) >>8; /* size[1] */
78 mbr[460]=(datasize&0x00ff0000) >>16; /* size[2] */
79 mbr[461]=(datasize&0xff000000) >>24; /* size[3] */
80
81 mbr[462]=0; /* flags */
82 mbr[463]=h(firmwarestart); /* chs1[0] (h) */
83 mbr[464]=s(firmwarestart); /* chs1[1] (s) */
84 mbr[465]=c(firmwarestart); /* chs1[2] (c) */
85 mbr[466]=0x84; /* type */
86 mbr[467]=h(firmwarestart+firmwaresize-1); /* chs2[0] (h) */
87 mbr[468]=s(firmwarestart+firmwaresize-1); /* chs2[1] (s) */
88 mbr[469]=c(firmwarestart+firmwaresize-1); /* chs2[2] (c) */
89 mbr[470]=(firmwarestart&0x000000ffu); /* lba[0] */
90 mbr[471]=(firmwarestart&0x0000ff00u) >>8; /* lba[1] */
91 mbr[472]=(firmwarestart&0x00ff0000u) >>16; /* lba[2] */
92 mbr[473]=(firmwarestart&0xff000000u) >>24; /* lba[3] */
93 mbr[474]=(firmwaresize&0x000000ffu); /* size[0] */
94 mbr[475]=(firmwaresize&0x0000ff00u) >>8; /* size[1] */
95 mbr[476]=(firmwaresize&0x00ff0000u) >>16; /* size[2] */
96 mbr[477]=(firmwaresize&0xff000000u) >>24; /* size[3] */
97
98 mbr[510]=0x55;
99 mbr[511]=0xaa;
100
101 int res = storage_write_sectors(0,1,mbr);
102 if(res != 0)
103 {
104 return -1;
105 }
106 return 0;
107}
108
109/* Hack. We "steal" line from common.c to reset the line number
110 * so we can overwrite the previous line for nicer progress info
111 */
112extern int line;
113int wipe(int size, int verify)
114{
115 int i;
116 int res;
117 int sectors = sizeof(nonzero)/512;
118 for(i=0;i<size;i+=sectors)
119 {
120 if(verify)
121 {
122 res = storage_write_sectors(i,sectors,nonzero);
123 if(res != 0)
124 {
125 printf("write error (1) on sector %d (of %d)!",i,size);
126 return -1;
127 }
128 res = storage_read_sectors(i,sectors,scratch);
129 if(res != 0)
130 {
131 printf("read error (1) on sector %d (of %d)!",i,size);
132 return -1;
133 }
134 res = memcmp(nonzero, scratch, sizeof(nonzero));
135 if(res != 0)
136 {
137 printf("compare error (1) on sector %d (of %d)!",i,size);
138 return -1;
139 }
140 }
141 res = storage_write_sectors(i,sectors,zero);
142 if(res != 0)
143 {
144 printf("write error (2) on sector %d (of %d)!",i,size);
145 return -1;
146 }
147 if(verify)
148 {
149 res = storage_read_sectors(i,sectors,scratch);
150 if(res != 0)
151 {
152 printf("read error (2) on sector %d (of %d)!",i,size);
153 return -1;
154 }
155 res = memcmp(zero, scratch, sizeof(nonzero));
156 if(res != 0)
157 {
158 printf("compare error (2) on sector %d (of %d)!",i,size);
159 return -1;
160 }
161 }
162
163 if(i%2048 == 0)
164 {
165 printf("%d of %d MB done",i/2048, size/2048);
166 /* Hack to overwrite the previous line */
167 line--;
168 }
169 }
170 return 0;
171}
172
173void* main(void)
174{
175 int i;
176 int btn;
177
Frank Gevaerts2b9e9442011-09-02 21:34:28 +0000178 system_init();
179 kernel_init();
180 lcd_init();
181 font_init();
182 button_init();
183 i2c_init();
Marcin Bukat89ba7e82015-01-09 00:22:40 +0100184 backlight_hw_on();
Frank Gevaerts2b9e9442011-09-02 21:34:28 +0000185
186 lcd_set_foreground(LCD_WHITE);
187 lcd_set_background(LCD_BLACK);
188 lcd_clear_display();
189
190 btn = button_read_device();
191 verbose = true;
192
193 lcd_setfont(FONT_SYSFIXED);
194
195 printf("Sansa initialiser");
196 printf("");
197
198
199 i=storage_init();
200 disk_init(IF_MD(0));
201
202 storage_get_info(0,&info);
203 int size = info.num_sectors;
204 memset(zero,0,sizeof(zero));
205 memset(nonzero,0xff,sizeof(nonzero));
206 printf("Zeroing flash");
207 int res;
208
209 res = wipe(size, 0);
210 if(res != 0)
211 {
212 printf("error wiping flash");
213 }
214
215 int firmwaresize = 0xa000;
216 int firmwarestart = size - firmwaresize;
217 int datastart = 600;
218 int datasize = firmwarestart - datastart;
219
220 res = write_mbr(datastart,datasize,firmwarestart,firmwaresize);
221 if(res != 0)
222 {
223 printf("error writing mbr");
224 }
225 res = format_partition(datastart, datasize);
226 if(res != 0)
227 {
228 printf("error formatting");
229 }
230
231 printf("Wipe done.");
232 if (button_hold())
233 printf("Release Hold and");
234 printf("press any key to");
235 printf("shutdown.");
236
237 printf("Remember to use");
238 printf("manufacturing");
239 printf("mode to recover");
240 printf("further");
241
242 while(button_read_device() == BUTTON_NONE);
243
244 power_off();
245
246 return NULL;
247}