• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <boot/boot.h>
30 #include <boot/uart.h>
31 #include <boot/tags.h>
32 #include <boot/flash.h>
33 #include <boot/board.h>
34 
35 #include <bootimg.h>
36 
37 #define FLASH_PAGE_SIZE 2048
38 #define FLASH_PAGE_BITS 11
39 
40 #define ADDR_TAGS    0x10000100
41 
create_atags(unsigned taddr,const char * cmdline,unsigned raddr,unsigned rsize)42 static void create_atags(unsigned taddr, const char *cmdline,
43                          unsigned raddr, unsigned rsize)
44 {
45     unsigned n = 0;
46     unsigned pcount;
47     unsigned *tags = (unsigned *) taddr;
48 
49         // ATAG_CORE
50     tags[n++] = 2;
51     tags[n++] = 0x54410001;
52 
53     if(rsize) {
54         // ATAG_INITRD2
55         tags[n++] = 4;
56         tags[n++] = 0x54420005;
57         tags[n++] = raddr;
58         tags[n++] = rsize;
59     }
60 
61     if((pcount = flash_get_ptn_count())){
62         ptentry *ptn;
63         unsigned pn;
64         unsigned m = n + 2;
65 
66         for(pn = 0; pn < pcount; pn++) {
67             ptn = flash_get_ptn(pn);
68             memcpy(tags + m, ptn, sizeof(ptentry));
69             m += (sizeof(ptentry) / sizeof(unsigned));
70         }
71 
72         tags[n + 0] = m - n;
73         tags[n + 1] = 0x4d534d70;
74         n = m;
75     }
76     if(cmdline && cmdline[0]) {
77         const char *src;
78         char *dst;
79         unsigned len = 0;
80 
81         dst = (char*) (tags + n + 2);
82         src = cmdline;
83         while((*dst++ = *src++)) len++;
84 
85         len++;
86         len = (len + 3) & (~3);
87 
88             // ATAG_CMDLINE
89         tags[n++] = 2 + (len / 4);
90         tags[n++] = 0x54410009;
91 
92         n += (len / 4);
93     }
94 
95         // ATAG_NONE
96     tags[n++] = 0;
97     tags[n++] = 0;
98 }
99 
boot_linux(unsigned kaddr)100 static void boot_linux(unsigned kaddr)
101 {
102     void (*entry)(unsigned,unsigned,unsigned) = (void*) kaddr;
103 
104     entry(0, board_machtype(), ADDR_TAGS);
105 }
106 
107 unsigned char raw_header[2048];
108 
boot_linux_from_flash(void)109 int boot_linux_from_flash(void)
110 {
111     boot_img_hdr *hdr = (void*) raw_header;
112     unsigned n;
113     ptentry *p;
114     unsigned offset = 0;
115     const char *cmdline;
116 
117     if((p = flash_find_ptn("boot")) == 0) {
118         cprintf("NO BOOT PARTITION\n");
119         return -1;
120     }
121 
122     if(flash_read(p, offset, raw_header, 2048)) {
123         cprintf("CANNOT READ BOOT IMAGE HEADER\n");
124         return -1;
125     }
126     offset += 2048;
127 
128     if(memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
129         cprintf("INVALID BOOT IMAGE HEADER\n");
130         return -1;
131     }
132 
133     n = (hdr->kernel_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));
134     if(flash_read(p, offset, (void*) hdr->kernel_addr, n)) {
135         cprintf("CANNOT READ KERNEL IMAGE\n");
136         return -1;
137     }
138     offset += n;
139 
140     n = (hdr->ramdisk_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));
141     if(flash_read(p, offset, (void*) hdr->ramdisk_addr, n)) {
142         cprintf("CANNOT READ RAMDISK IMAGE\n");
143         return -1;
144     }
145     offset += n;
146 
147     dprintf("\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr, hdr->kernel_size);
148     dprintf("ramdisk @ %x (%d bytes)\n\n\n", hdr->ramdisk_addr, hdr->ramdisk_size);
149 
150     if(hdr->cmdline[0]) {
151         cmdline = (char*) hdr->cmdline;
152     } else {
153         cmdline = board_cmdline();
154         if(cmdline == 0) {
155             cmdline = "mem=50M console=null";
156         }
157     }
158     cprintf("cmdline = '%s'\n", cmdline);
159 
160     cprintf("\nBooting Linux\n");
161 
162     create_atags(ADDR_TAGS, cmdline,
163                  hdr->ramdisk_addr, hdr->ramdisk_size);
164 
165     boot_linux(hdr->kernel_addr);
166     return 0;
167 }
168 
169 void usbloader_init(void);
170 void uart_putc(unsigned);
171 const char *get_fastboot_version(void);
172 
173 extern unsigned linux_type;
174 extern unsigned linux_tags;
175 
176 static unsigned revision = 0;
177 
178 char serialno[32];
179 
180 void dump_smem_info(void);
181 
tag_dump(unsigned tag,void * data,unsigned sz,void * cookie)182 static void tag_dump(unsigned tag, void *data, unsigned sz, void *cookie)
183 {
184     dprintf("tag type=%x data=%x size=%x\n", tag, (unsigned) data, sz);
185 }
186 
187 static struct tag_handler tag_dump_handler = {
188     .func = tag_dump,
189     .type = 0,
190 };
191 
xdcc_putc(unsigned x)192 void xdcc_putc(unsigned x)
193 {
194     while (dcc_putc(x) < 0) ;
195 }
196 
197 #define SERIALNO_STR "androidboot.serialno="
198 #define SERIALNO_LEN strlen(SERIALNO_STR)
199 
200 static int boot_from_flash = 1;
201 
key_changed(unsigned int key,unsigned int down)202 void key_changed(unsigned int key, unsigned int down)
203 {
204     if(!down) return;
205     if(key == BOOT_KEY_STOP_BOOT) boot_from_flash = 0;
206 }
207 
tags_okay(unsigned taddr)208 static int tags_okay(unsigned taddr)
209 {
210     unsigned *tags = (unsigned*) taddr;
211 
212     if(taddr != ADDR_TAGS) return 0;
213     if(tags[0] != 2) return 0;
214     if(tags[1] != 0x54410001) return 0;
215 
216     return 1;
217 }
218 
_main(unsigned zero,unsigned type,unsigned tags)219 int _main(unsigned zero, unsigned type, unsigned tags)
220 {
221     const char *cmdline = 0;
222     int n;
223 
224     arm11_clock_init();
225 
226         /* must do this before board_init() so that we
227         ** use the partition table in the tags if it
228         ** already exists
229         */
230     if((zero == 0) && (type != 0) && tags_okay(tags)) {
231         linux_type = type;
232         linux_tags = tags;
233 
234         cmdline = tags_get_cmdline((void*) linux_tags);
235 
236         tags_import_partitions((void*) linux_tags);
237         revision = tags_get_revision((void*) linux_tags);
238         if(revision == 1) {
239             console_set_colors(0x03E0, 0xFFFF);
240         }
241         if(revision == 2) {
242             console_set_colors(0x49B2, 0xFFFF);
243         }
244 
245             /* we're running as a second-stage, so wait for interrupt */
246         boot_from_flash = 0;
247     } else {
248         linux_type = board_machtype();
249         linux_tags = 0;
250     }
251 
252     board_init();
253     keypad_init();
254 
255     console_init();
256     dprintf_set_putc(uart_putc);
257 
258     if(linux_tags == 0) {
259             /* generate atags containing partitions
260              * from the bootloader, etc
261              */
262         linux_tags = ADDR_TAGS;
263         create_atags(linux_tags, 0, 0, 0);
264     }
265 
266     if (cmdline) {
267         char *sn = strstr(cmdline, SERIALNO_STR);
268         if (sn) {
269             char *s = serialno;
270             sn += SERIALNO_LEN;
271             while (*sn && (*sn != ' ') && ((s - serialno) < 31)) {
272                 *s++ = *sn++;
273             }
274             *s++ = 0;
275         }
276     }
277 
278     cprintf("\n\nUSB FastBoot:  V%s\n", get_fastboot_version());
279     cprintf("Machine ID:    %d v%d\n", linux_type, revision);
280     cprintf("Build Date:    "__DATE__", "__TIME__"\n\n");
281 
282     cprintf("Serial Number: %s\n\n", serialno[0] ? serialno : "UNKNOWN");
283 
284     flash_dump_ptn();
285 
286     flash_init();
287 
288         /* scan the keyboard a bit */
289     for(n = 0; n < 50; n++) {
290         boot_poll();
291     }
292 
293     if (boot_from_flash) {
294         cprintf("\n ** BOOTING LINUX FROM FLASH **\n");
295         boot_linux_from_flash();
296     }
297 
298     usbloader_init();
299 
300     for(;;) {
301         usb_poll();
302     }
303     return 0;
304 }
305