-
Notifications
You must be signed in to change notification settings - Fork 40
/
boot.c
111 lines (93 loc) · 3.28 KB
/
boot.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Copyright (C) 2011 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <aboot/aboot.h>
#include <aboot/bootimg.h>
int boot_image(unsigned machtype, unsigned image, unsigned len)
{
void (*entry)(unsigned, unsigned, unsigned);
struct boot_img_hdr *hdr = (void*) image;
unsigned psize, pmask, kactual;
unsigned *tag = (void*) CONFIG_ADDR_ATAGS;
unsigned n;
char *x = (void*) image;
for (n = 0; n < 8; n++)
if (x[n] != "ANDROID!"[n]) break;
if (n != 8) {
printf("jumping to 0x%x...\n", CONFIG_ADDR_DOWNLOAD);
entry = CONFIG_ADDR_DOWNLOAD;
entry(0, cfg_machine_type, CONFIG_ADDR_ATAGS);
for (;;);
}
if (len < sizeof(*hdr))
return -1;
psize = hdr->page_size;
pmask = hdr->page_size - 1;
if ((psize != 1024) && (psize != 2048) && (psize != 4096))
return -1;
if (len < psize)
return -1;
kactual = (hdr->kernel_size + pmask) & (~pmask);
/* CORE */
*tag++ = 2;
*tag++ = 0x54410001;
if (hdr->ramdisk_size) {
*tag++ = 4;
*tag++ = 0x54420005;
*tag++ = image + psize + kactual;
*tag++ = hdr->ramdisk_size;
}
if (hdr->cmdline && hdr->cmdline[0]) {
/* include terminating 0 and word align */
unsigned n = (strlen((void*) hdr->cmdline) + 4) & (~3);
*tag++ = (n / 4) + 2;
*tag++ = 0x54410009;
memcpy(tag, hdr->cmdline, n);
tag += (n / 4);
}
/* END */
*tag++ = 0;
*tag++ = 0;
/* need to move the kernel away from the ramdisk-in-bootimg
* otherwise the ramdisk gets clobbered before it can be
* uncompressed.
*/
memcpy((void*) CONFIG_ADDR_KERNEL, image + psize, kactual);
entry = (void*) CONFIG_ADDR_KERNEL;
printf("kernel: 0x%x (%d bytes)\n",
CONFIG_ADDR_KERNEL, hdr->kernel_size);
printf("ramdisk: 0x%x (%d bytes)\n",
image + psize + kactual, hdr->ramdisk_size);
printf("atags: 0x%x\n", CONFIG_ADDR_ATAGS);
printf("cmdline: %s\n", hdr->cmdline);
printf("machtype: %d\n", machtype);
serial_puts("\nbooting...\n");
entry(0, machtype, CONFIG_ADDR_ATAGS);
serial_puts("\nreturned from kernel?\n");
for (;;) ;
return 0;
}