diff options
-rw-r--r-- | mkbootimg/mkbootimg.c | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c deleted file mode 100644 index 40e52610d..000000000 --- a/mkbootimg/mkbootimg.c +++ /dev/null | |||
@@ -1,297 +0,0 @@ | |||
1 | /* tools/mkbootimg/mkbootimg.c | ||
2 | ** | ||
3 | ** Copyright 2007, The Android Open Source Project | ||
4 | ** | ||
5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | ** you may not use this file except in compliance with the License. | ||
7 | ** You may obtain a copy of the License at | ||
8 | ** | ||
9 | ** http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | ** | ||
11 | ** Unless required by applicable law or agreed to in writing, software | ||
12 | ** distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | ** See the License for the specific language governing permissions and | ||
15 | ** limitations under the License. | ||
16 | */ | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <string.h> | ||
21 | #include <unistd.h> | ||
22 | #include <fcntl.h> | ||
23 | #include <errno.h> | ||
24 | #include <stdbool.h> | ||
25 | |||
26 | #include "mincrypt/sha.h" | ||
27 | #include "bootimg.h" | ||
28 | |||
29 | static void *load_file(const char *fn, unsigned *_sz) | ||
30 | { | ||
31 | char *data; | ||
32 | int sz; | ||
33 | int fd; | ||
34 | |||
35 | data = 0; | ||
36 | fd = open(fn, O_RDONLY); | ||
37 | if(fd < 0) return 0; | ||
38 | |||
39 | sz = lseek(fd, 0, SEEK_END); | ||
40 | if(sz < 0) goto oops; | ||
41 | |||
42 | if(lseek(fd, 0, SEEK_SET) != 0) goto oops; | ||
43 | |||
44 | data = (char*) malloc(sz); | ||
45 | if(data == 0) goto oops; | ||
46 | |||
47 | if(read(fd, data, sz) != sz) goto oops; | ||
48 | close(fd); | ||
49 | |||
50 | if(_sz) *_sz = sz; | ||
51 | return data; | ||
52 | |||
53 | oops: | ||
54 | close(fd); | ||
55 | if(data != 0) free(data); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | int usage(void) | ||
60 | { | ||
61 | fprintf(stderr,"usage: mkbootimg\n" | ||
62 | " --kernel <filename>\n" | ||
63 | " --ramdisk <filename>\n" | ||
64 | " [ --second <2ndbootloader-filename> ]\n" | ||
65 | " [ --cmdline <kernel-commandline> ]\n" | ||
66 | " [ --board <boardname> ]\n" | ||
67 | " [ --base <address> ]\n" | ||
68 | " [ --pagesize <pagesize> ]\n" | ||
69 | " [ --id ]\n" | ||
70 | " -o|--output <filename>\n" | ||
71 | ); | ||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | |||
76 | |||
77 | static unsigned char padding[16384] = { 0, }; | ||
78 | |||
79 | static void print_id(const uint8_t *id, size_t id_len) { | ||
80 | printf("0x"); | ||
81 | for (unsigned i = 0; i < id_len; i++) { | ||
82 | printf("%02x", id[i]); | ||
83 | } | ||
84 | printf("\n"); | ||
85 | } | ||
86 | |||
87 | int write_padding(int fd, unsigned pagesize, unsigned itemsize) | ||
88 | { | ||
89 | unsigned pagemask = pagesize - 1; | ||
90 | ssize_t count; | ||
91 | |||
92 | if((itemsize & pagemask) == 0) { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | count = pagesize - (itemsize & pagemask); | ||
97 | |||
98 | if(write(fd, padding, count) != count) { | ||
99 | return -1; | ||
100 | } else { | ||
101 | return 0; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | int main(int argc, char **argv) | ||
106 | { | ||
107 | boot_img_hdr hdr; | ||
108 | |||
109 | char *kernel_fn = NULL; | ||
110 | void *kernel_data = NULL; | ||
111 | char *ramdisk_fn = NULL; | ||
112 | void *ramdisk_data = NULL; | ||
113 | char *second_fn = NULL; | ||
114 | void *second_data = NULL; | ||
115 | char *cmdline = ""; | ||
116 | char *bootimg = NULL; | ||
117 | char *board = ""; | ||
118 | uint32_t pagesize = 2048; | ||
119 | int fd; | ||
120 | SHA_CTX ctx; | ||
121 | const uint8_t* sha; | ||
122 | uint32_t base = 0x10000000U; | ||
123 | uint32_t kernel_offset = 0x00008000U; | ||
124 | uint32_t ramdisk_offset = 0x01000000U; | ||
125 | uint32_t second_offset = 0x00f00000U; | ||
126 | uint32_t tags_offset = 0x00000100U; | ||
127 | size_t cmdlen; | ||
128 | |||
129 | argc--; | ||
130 | argv++; | ||
131 | |||
132 | memset(&hdr, 0, sizeof(hdr)); | ||
133 | |||
134 | bool get_id = false; | ||
135 | while(argc > 0){ | ||
136 | char *arg = argv[0]; | ||
137 | if (!strcmp(arg, "--id")) { | ||
138 | get_id = true; | ||
139 | argc -= 1; | ||
140 | argv += 1; | ||
141 | } else if(argc >= 2) { | ||
142 | char *val = argv[1]; | ||
143 | argc -= 2; | ||
144 | argv += 2; | ||
145 | if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { | ||
146 | bootimg = val; | ||
147 | } else if(!strcmp(arg, "--kernel")) { | ||
148 | kernel_fn = val; | ||
149 | } else if(!strcmp(arg, "--ramdisk")) { | ||
150 | ramdisk_fn = val; | ||
151 | } else if(!strcmp(arg, "--second")) { | ||
152 | second_fn = val; | ||
153 | } else if(!strcmp(arg, "--cmdline")) { | ||
154 | cmdline = val; | ||
155 | } else if(!strcmp(arg, "--base")) { | ||
156 | base = strtoul(val, 0, 16); | ||
157 | } else if(!strcmp(arg, "--kernel_offset")) { | ||
158 | kernel_offset = strtoul(val, 0, 16); | ||
159 | } else if(!strcmp(arg, "--ramdisk_offset")) { | ||
160 | ramdisk_offset = strtoul(val, 0, 16); | ||
161 | } else if(!strcmp(arg, "--second_offset")) { | ||
162 | second_offset = strtoul(val, 0, 16); | ||
163 | } else if(!strcmp(arg, "--tags_offset")) { | ||
164 | tags_offset = strtoul(val, 0, 16); | ||
165 | } else if(!strcmp(arg, "--board")) { | ||
166 | board = val; | ||
167 | } else if(!strcmp(arg,"--pagesize")) { | ||
168 | pagesize = strtoul(val, 0, 10); | ||
169 | if ((pagesize != 2048) && (pagesize != 4096) | ||
170 | && (pagesize != 8192) && (pagesize != 16384)) { | ||
171 | fprintf(stderr,"error: unsupported page size %d\n", pagesize); | ||
172 | return -1; | ||
173 | } | ||
174 | } else { | ||
175 | return usage(); | ||
176 | } | ||
177 | } else { | ||
178 | return usage(); | ||
179 | } | ||
180 | } | ||
181 | hdr.page_size = pagesize; | ||
182 | |||
183 | hdr.kernel_addr = base + kernel_offset; | ||
184 | hdr.ramdisk_addr = base + ramdisk_offset; | ||
185 | hdr.second_addr = base + second_offset; | ||
186 | hdr.tags_addr = base + tags_offset; | ||
187 | |||
188 | if(bootimg == 0) { | ||
189 | fprintf(stderr,"error: no output filename specified\n"); | ||
190 | return usage(); | ||
191 | } | ||
192 | |||
193 | if(kernel_fn == 0) { | ||
194 | fprintf(stderr,"error: no kernel image specified\n"); | ||
195 | return usage(); | ||
196 | } | ||
197 | |||
198 | if(ramdisk_fn == 0) { | ||
199 | fprintf(stderr,"error: no ramdisk image specified\n"); | ||
200 | return usage(); | ||
201 | } | ||
202 | |||
203 | if(strlen(board) >= BOOT_NAME_SIZE) { | ||
204 | fprintf(stderr,"error: board name too large\n"); | ||
205 | return usage(); | ||
206 | } | ||
207 | |||
208 | strcpy((char *) hdr.name, board); | ||
209 | |||
210 | memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); | ||
211 | |||
212 | cmdlen = strlen(cmdline); | ||
213 | if(cmdlen > (BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 2)) { | ||
214 | fprintf(stderr,"error: kernel commandline too large\n"); | ||
215 | return 1; | ||
216 | } | ||
217 | /* Even if we need to use the supplemental field, ensure we | ||
218 | * are still NULL-terminated */ | ||
219 | strncpy((char *)hdr.cmdline, cmdline, BOOT_ARGS_SIZE - 1); | ||
220 | hdr.cmdline[BOOT_ARGS_SIZE - 1] = '\0'; | ||
221 | if (cmdlen >= (BOOT_ARGS_SIZE - 1)) { | ||
222 | cmdline += (BOOT_ARGS_SIZE - 1); | ||
223 | strncpy((char *)hdr.extra_cmdline, cmdline, BOOT_EXTRA_ARGS_SIZE); | ||
224 | } | ||
225 | |||
226 | kernel_data = load_file(kernel_fn, &hdr.kernel_size); | ||
227 | if(kernel_data == 0) { | ||
228 | fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); | ||
229 | return 1; | ||
230 | } | ||
231 | |||
232 | if(!strcmp(ramdisk_fn,"NONE")) { | ||
233 | ramdisk_data = 0; | ||
234 | hdr.ramdisk_size = 0; | ||
235 | } else { | ||
236 | ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); | ||
237 | if(ramdisk_data == 0) { | ||
238 | fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); | ||
239 | return 1; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | if(second_fn) { | ||
244 | second_data = load_file(second_fn, &hdr.second_size); | ||
245 | if(second_data == 0) { | ||
246 | fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); | ||
247 | return 1; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /* put a hash of the contents in the header so boot images can be | ||
252 | * differentiated based on their first 2k. | ||
253 | */ | ||
254 | SHA_init(&ctx); | ||
255 | SHA_update(&ctx, kernel_data, hdr.kernel_size); | ||
256 | SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); | ||
257 | SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); | ||
258 | SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); | ||
259 | SHA_update(&ctx, second_data, hdr.second_size); | ||
260 | SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); | ||
261 | sha = SHA_final(&ctx); | ||
262 | memcpy(hdr.id, sha, | ||
263 | SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); | ||
264 | |||
265 | fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); | ||
266 | if(fd < 0) { | ||
267 | fprintf(stderr,"error: could not create '%s'\n", bootimg); | ||
268 | return 1; | ||
269 | } | ||
270 | |||
271 | if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; | ||
272 | if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; | ||
273 | |||
274 | if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail; | ||
275 | if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; | ||
276 | |||
277 | if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail; | ||
278 | if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; | ||
279 | |||
280 | if(second_data) { | ||
281 | if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail; | ||
282 | if(write_padding(fd, pagesize, hdr.second_size)) goto fail; | ||
283 | } | ||
284 | |||
285 | if (get_id) { | ||
286 | print_id((uint8_t *) hdr.id, sizeof(hdr.id)); | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | |||
291 | fail: | ||
292 | unlink(bootimg); | ||
293 | close(fd); | ||
294 | fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, | ||
295 | strerror(errno)); | ||
296 | return 1; | ||
297 | } | ||