Commit b639640371ed38c76602387af865b814967473ba
bootm: Split out code from cmd_bootm.c
This file has code in three different categories: - Command processing - OS-specific boot code - Locating images and setting up to boot Only the first category really belongs in a file called cmd_bootm.c. Leave the command processing code where it is. Split out the OS-specific boot code into bootm_os.c. Split out the other code into bootm.c Header files and extern declarations are tidied but otherwise no code changes are made, to make it easier to review. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 5 changed files with 1356 additions and 1338 deletions Side-by-side Diff
1 | +/* | |
2 | + * (C) Copyright 2000-2009 | |
3 | + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <bootm.h> | |
10 | +#include <bzlib.h> | |
11 | +#include <image.h> | |
12 | +#include <fdt_support.h> | |
13 | +#include <lmb.h> | |
14 | +#include <malloc.h> | |
15 | +#include <asm/io.h> | |
16 | +#include <linux/lzo.h> | |
17 | +#include <lzma/LzmaTypes.h> | |
18 | +#include <lzma/LzmaDec.h> | |
19 | +#include <lzma/LzmaTools.h> | |
20 | + | |
21 | +#if defined(CONFIG_CMD_USB) | |
22 | +#include <usb.h> | |
23 | +#endif | |
24 | + | |
25 | +DECLARE_GLOBAL_DATA_PTR; | |
26 | + | |
27 | +#ifndef CONFIG_SYS_BOOTM_LEN | |
28 | +/* use 8MByte as default max gunzip size */ | |
29 | +#define CONFIG_SYS_BOOTM_LEN 0x800000 | |
30 | +#endif | |
31 | + | |
32 | +#define IH_INITRD_ARCH IH_ARCH_DEFAULT | |
33 | + | |
34 | +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, | |
35 | + char * const argv[], bootm_headers_t *images, | |
36 | + ulong *os_data, ulong *os_len); | |
37 | + | |
38 | +#ifdef CONFIG_LMB | |
39 | +static void boot_start_lmb(bootm_headers_t *images) | |
40 | +{ | |
41 | + ulong mem_start; | |
42 | + phys_size_t mem_size; | |
43 | + | |
44 | + lmb_init(&images->lmb); | |
45 | + | |
46 | + mem_start = getenv_bootm_low(); | |
47 | + mem_size = getenv_bootm_size(); | |
48 | + | |
49 | + lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); | |
50 | + | |
51 | + arch_lmb_reserve(&images->lmb); | |
52 | + board_lmb_reserve(&images->lmb); | |
53 | +} | |
54 | +#else | |
55 | +#define lmb_reserve(lmb, base, size) | |
56 | +static inline void boot_start_lmb(bootm_headers_t *images) { } | |
57 | +#endif | |
58 | + | |
59 | +static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, | |
60 | + char * const argv[]) | |
61 | +{ | |
62 | + memset((void *)&images, 0, sizeof(images)); | |
63 | + images.verify = getenv_yesno("verify"); | |
64 | + | |
65 | + boot_start_lmb(&images); | |
66 | + | |
67 | + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); | |
68 | + images.state = BOOTM_STATE_START; | |
69 | + | |
70 | + return 0; | |
71 | +} | |
72 | + | |
73 | +static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, | |
74 | + char * const argv[]) | |
75 | +{ | |
76 | + const void *os_hdr; | |
77 | + bool ep_found = false; | |
78 | + | |
79 | + /* get kernel image header, start address and length */ | |
80 | + os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, | |
81 | + &images, &images.os.image_start, &images.os.image_len); | |
82 | + if (images.os.image_len == 0) { | |
83 | + puts("ERROR: can't get kernel image!\n"); | |
84 | + return 1; | |
85 | + } | |
86 | + | |
87 | + /* get image parameters */ | |
88 | + switch (genimg_get_format(os_hdr)) { | |
89 | +#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
90 | + case IMAGE_FORMAT_LEGACY: | |
91 | + images.os.type = image_get_type(os_hdr); | |
92 | + images.os.comp = image_get_comp(os_hdr); | |
93 | + images.os.os = image_get_os(os_hdr); | |
94 | + | |
95 | + images.os.end = image_get_image_end(os_hdr); | |
96 | + images.os.load = image_get_load(os_hdr); | |
97 | + break; | |
98 | +#endif | |
99 | +#if defined(CONFIG_FIT) | |
100 | + case IMAGE_FORMAT_FIT: | |
101 | + if (fit_image_get_type(images.fit_hdr_os, | |
102 | + images.fit_noffset_os, | |
103 | + &images.os.type)) { | |
104 | + puts("Can't get image type!\n"); | |
105 | + bootstage_error(BOOTSTAGE_ID_FIT_TYPE); | |
106 | + return 1; | |
107 | + } | |
108 | + | |
109 | + if (fit_image_get_comp(images.fit_hdr_os, | |
110 | + images.fit_noffset_os, | |
111 | + &images.os.comp)) { | |
112 | + puts("Can't get image compression!\n"); | |
113 | + bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); | |
114 | + return 1; | |
115 | + } | |
116 | + | |
117 | + if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os, | |
118 | + &images.os.os)) { | |
119 | + puts("Can't get image OS!\n"); | |
120 | + bootstage_error(BOOTSTAGE_ID_FIT_OS); | |
121 | + return 1; | |
122 | + } | |
123 | + | |
124 | + images.os.end = fit_get_end(images.fit_hdr_os); | |
125 | + | |
126 | + if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, | |
127 | + &images.os.load)) { | |
128 | + puts("Can't get image load address!\n"); | |
129 | + bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); | |
130 | + return 1; | |
131 | + } | |
132 | + break; | |
133 | +#endif | |
134 | +#ifdef CONFIG_ANDROID_BOOT_IMAGE | |
135 | + case IMAGE_FORMAT_ANDROID: | |
136 | + images.os.type = IH_TYPE_KERNEL; | |
137 | + images.os.comp = IH_COMP_NONE; | |
138 | + images.os.os = IH_OS_LINUX; | |
139 | + images.ep = images.os.load; | |
140 | + ep_found = true; | |
141 | + | |
142 | + images.os.end = android_image_get_end(os_hdr); | |
143 | + images.os.load = android_image_get_kload(os_hdr); | |
144 | + break; | |
145 | +#endif | |
146 | + default: | |
147 | + puts("ERROR: unknown image format type!\n"); | |
148 | + return 1; | |
149 | + } | |
150 | + | |
151 | + /* find kernel entry point */ | |
152 | + if (images.legacy_hdr_valid) { | |
153 | + images.ep = image_get_ep(&images.legacy_hdr_os_copy); | |
154 | +#if defined(CONFIG_FIT) | |
155 | + } else if (images.fit_uname_os) { | |
156 | + int ret; | |
157 | + | |
158 | + ret = fit_image_get_entry(images.fit_hdr_os, | |
159 | + images.fit_noffset_os, &images.ep); | |
160 | + if (ret) { | |
161 | + puts("Can't get entry point property!\n"); | |
162 | + return 1; | |
163 | + } | |
164 | +#endif | |
165 | + } else if (!ep_found) { | |
166 | + puts("Could not find kernel entry point!\n"); | |
167 | + return 1; | |
168 | + } | |
169 | + | |
170 | + if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { | |
171 | + images.os.load = images.os.image_start; | |
172 | + images.ep += images.os.load; | |
173 | + } | |
174 | + | |
175 | + images.os.start = (ulong)os_hdr; | |
176 | + | |
177 | + return 0; | |
178 | +} | |
179 | + | |
180 | +static int bootm_find_ramdisk(int flag, int argc, char * const argv[]) | |
181 | +{ | |
182 | + int ret; | |
183 | + | |
184 | + /* find ramdisk */ | |
185 | + ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, | |
186 | + &images.rd_start, &images.rd_end); | |
187 | + if (ret) { | |
188 | + puts("Ramdisk image is corrupt or invalid\n"); | |
189 | + return 1; | |
190 | + } | |
191 | + | |
192 | + return 0; | |
193 | +} | |
194 | + | |
195 | +#if defined(CONFIG_OF_LIBFDT) | |
196 | +static int bootm_find_fdt(int flag, int argc, char * const argv[]) | |
197 | +{ | |
198 | + int ret; | |
199 | + | |
200 | + /* find flattened device tree */ | |
201 | + ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, | |
202 | + &images.ft_addr, &images.ft_len); | |
203 | + if (ret) { | |
204 | + puts("Could not find a valid device tree\n"); | |
205 | + return 1; | |
206 | + } | |
207 | + | |
208 | + set_working_fdt_addr(images.ft_addr); | |
209 | + | |
210 | + return 0; | |
211 | +} | |
212 | +#endif | |
213 | + | |
214 | +int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]) | |
215 | +{ | |
216 | + if (bootm_find_ramdisk(flag, argc, argv)) | |
217 | + return 1; | |
218 | + | |
219 | +#if defined(CONFIG_OF_LIBFDT) | |
220 | + if (bootm_find_fdt(flag, argc, argv)) | |
221 | + return 1; | |
222 | +#endif | |
223 | + | |
224 | + return 0; | |
225 | +} | |
226 | + | |
227 | +static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, | |
228 | + char * const argv[]) | |
229 | +{ | |
230 | + if (((images.os.type == IH_TYPE_KERNEL) || | |
231 | + (images.os.type == IH_TYPE_KERNEL_NOLOAD) || | |
232 | + (images.os.type == IH_TYPE_MULTI)) && | |
233 | + (images.os.os == IH_OS_LINUX || | |
234 | + images.os.os == IH_OS_VXWORKS)) | |
235 | + return bootm_find_ramdisk_fdt(flag, argc, argv); | |
236 | + | |
237 | + return 0; | |
238 | +} | |
239 | + | |
240 | +static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, | |
241 | + int boot_progress) | |
242 | +{ | |
243 | + image_info_t os = images->os; | |
244 | + uint8_t comp = os.comp; | |
245 | + ulong load = os.load; | |
246 | + ulong blob_start = os.start; | |
247 | + ulong blob_end = os.end; | |
248 | + ulong image_start = os.image_start; | |
249 | + ulong image_len = os.image_len; | |
250 | + __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN; | |
251 | + int no_overlap = 0; | |
252 | + void *load_buf, *image_buf; | |
253 | +#if defined(CONFIG_LZMA) || defined(CONFIG_LZO) | |
254 | + int ret; | |
255 | +#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */ | |
256 | + | |
257 | + const char *type_name = genimg_get_type_name(os.type); | |
258 | + | |
259 | + load_buf = map_sysmem(load, unc_len); | |
260 | + image_buf = map_sysmem(image_start, image_len); | |
261 | + switch (comp) { | |
262 | + case IH_COMP_NONE: | |
263 | + if (load == image_start) { | |
264 | + printf(" XIP %s ... ", type_name); | |
265 | + no_overlap = 1; | |
266 | + } else { | |
267 | + printf(" Loading %s ... ", type_name); | |
268 | + memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); | |
269 | + } | |
270 | + *load_end = load + image_len; | |
271 | + break; | |
272 | +#ifdef CONFIG_GZIP | |
273 | + case IH_COMP_GZIP: | |
274 | + printf(" Uncompressing %s ... ", type_name); | |
275 | + if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) { | |
276 | + puts("GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover\n"); | |
277 | + if (boot_progress) | |
278 | + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
279 | + return BOOTM_ERR_RESET; | |
280 | + } | |
281 | + | |
282 | + *load_end = load + image_len; | |
283 | + break; | |
284 | +#endif /* CONFIG_GZIP */ | |
285 | +#ifdef CONFIG_BZIP2 | |
286 | + case IH_COMP_BZIP2: | |
287 | + printf(" Uncompressing %s ... ", type_name); | |
288 | + /* | |
289 | + * If we've got less than 4 MB of malloc() space, | |
290 | + * use slower decompression algorithm which requires | |
291 | + * at most 2300 KB of memory. | |
292 | + */ | |
293 | + int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len, | |
294 | + image_buf, image_len, | |
295 | + CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); | |
296 | + if (i != BZ_OK) { | |
297 | + printf("BUNZIP2: uncompress or overwrite error %d - must RESET board to recover\n", | |
298 | + i); | |
299 | + if (boot_progress) | |
300 | + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
301 | + return BOOTM_ERR_RESET; | |
302 | + } | |
303 | + | |
304 | + *load_end = load + unc_len; | |
305 | + break; | |
306 | +#endif /* CONFIG_BZIP2 */ | |
307 | +#ifdef CONFIG_LZMA | |
308 | + case IH_COMP_LZMA: { | |
309 | + SizeT lzma_len = unc_len; | |
310 | + printf(" Uncompressing %s ... ", type_name); | |
311 | + | |
312 | + ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, | |
313 | + image_buf, image_len); | |
314 | + unc_len = lzma_len; | |
315 | + if (ret != SZ_OK) { | |
316 | + printf("LZMA: uncompress or overwrite error %d - must RESET board to recover\n", | |
317 | + ret); | |
318 | + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
319 | + return BOOTM_ERR_RESET; | |
320 | + } | |
321 | + *load_end = load + unc_len; | |
322 | + break; | |
323 | + } | |
324 | +#endif /* CONFIG_LZMA */ | |
325 | +#ifdef CONFIG_LZO | |
326 | + case IH_COMP_LZO: { | |
327 | + size_t size = unc_len; | |
328 | + | |
329 | + printf(" Uncompressing %s ... ", type_name); | |
330 | + | |
331 | + ret = lzop_decompress(image_buf, image_len, load_buf, &size); | |
332 | + if (ret != LZO_E_OK) { | |
333 | + printf("LZO: uncompress or overwrite error %d - must RESET board to recover\n", | |
334 | + ret); | |
335 | + if (boot_progress) | |
336 | + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
337 | + return BOOTM_ERR_RESET; | |
338 | + } | |
339 | + | |
340 | + *load_end = load + size; | |
341 | + break; | |
342 | + } | |
343 | +#endif /* CONFIG_LZO */ | |
344 | + default: | |
345 | + printf("Unimplemented compression type %d\n", comp); | |
346 | + return BOOTM_ERR_UNIMPLEMENTED; | |
347 | + } | |
348 | + | |
349 | + flush_cache(load, (*load_end - load) * sizeof(ulong)); | |
350 | + | |
351 | + puts("OK\n"); | |
352 | + debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); | |
353 | + bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED); | |
354 | + | |
355 | + if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) { | |
356 | + debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n", | |
357 | + blob_start, blob_end); | |
358 | + debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load, | |
359 | + *load_end); | |
360 | + | |
361 | + /* Check what type of image this is. */ | |
362 | + if (images->legacy_hdr_valid) { | |
363 | + if (image_get_type(&images->legacy_hdr_os_copy) | |
364 | + == IH_TYPE_MULTI) | |
365 | + puts("WARNING: legacy format multi component image overwritten\n"); | |
366 | + return BOOTM_ERR_OVERLAP; | |
367 | + } else { | |
368 | + puts("ERROR: new format image overwritten - must RESET the board to recover\n"); | |
369 | + bootstage_error(BOOTSTAGE_ID_OVERWRITTEN); | |
370 | + return BOOTM_ERR_RESET; | |
371 | + } | |
372 | + } | |
373 | + | |
374 | + return 0; | |
375 | +} | |
376 | + | |
377 | +/** | |
378 | + * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot | |
379 | + * | |
380 | + * @return interrupt flag (0 if interrupts were disabled, non-zero if they were | |
381 | + * enabled) | |
382 | + */ | |
383 | +ulong bootm_disable_interrupts(void) | |
384 | +{ | |
385 | + ulong iflag; | |
386 | + | |
387 | + /* | |
388 | + * We have reached the point of no return: we are going to | |
389 | + * overwrite all exception vector code, so we cannot easily | |
390 | + * recover from any failures any more... | |
391 | + */ | |
392 | + iflag = disable_interrupts(); | |
393 | +#ifdef CONFIG_NETCONSOLE | |
394 | + /* Stop the ethernet stack if NetConsole could have left it up */ | |
395 | + eth_halt(); | |
396 | + eth_unregister(eth_get_dev()); | |
397 | +#endif | |
398 | + | |
399 | +#if defined(CONFIG_CMD_USB) | |
400 | + /* | |
401 | + * turn off USB to prevent the host controller from writing to the | |
402 | + * SDRAM while Linux is booting. This could happen (at least for OHCI | |
403 | + * controller), because the HCCA (Host Controller Communication Area) | |
404 | + * lies within the SDRAM and the host controller writes continously to | |
405 | + * this area (as busmaster!). The HccaFrameNumber is for example | |
406 | + * updated every 1 ms within the HCCA structure in SDRAM! For more | |
407 | + * details see the OpenHCI specification. | |
408 | + */ | |
409 | + usb_stop(); | |
410 | +#endif | |
411 | + return iflag; | |
412 | +} | |
413 | + | |
414 | +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) | |
415 | + | |
416 | +#define CONSOLE_ARG "console=" | |
417 | +#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1) | |
418 | + | |
419 | +static void fixup_silent_linux(void) | |
420 | +{ | |
421 | + char *buf; | |
422 | + const char *env_val; | |
423 | + char *cmdline = getenv("bootargs"); | |
424 | + int want_silent; | |
425 | + | |
426 | + /* | |
427 | + * Only fix cmdline when requested. The environment variable can be: | |
428 | + * | |
429 | + * no - we never fixup | |
430 | + * yes - we always fixup | |
431 | + * unset - we rely on the console silent flag | |
432 | + */ | |
433 | + want_silent = getenv_yesno("silent_linux"); | |
434 | + if (want_silent == 0) | |
435 | + return; | |
436 | + else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT)) | |
437 | + return; | |
438 | + | |
439 | + debug("before silent fix-up: %s\n", cmdline); | |
440 | + if (cmdline && (cmdline[0] != '\0')) { | |
441 | + char *start = strstr(cmdline, CONSOLE_ARG); | |
442 | + | |
443 | + /* Allocate space for maximum possible new command line */ | |
444 | + buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1); | |
445 | + if (!buf) { | |
446 | + debug("%s: out of memory\n", __func__); | |
447 | + return; | |
448 | + } | |
449 | + | |
450 | + if (start) { | |
451 | + char *end = strchr(start, ' '); | |
452 | + int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN; | |
453 | + | |
454 | + strncpy(buf, cmdline, num_start_bytes); | |
455 | + if (end) | |
456 | + strcpy(buf + num_start_bytes, end); | |
457 | + else | |
458 | + buf[num_start_bytes] = '\0'; | |
459 | + } else { | |
460 | + sprintf(buf, "%s %s", cmdline, CONSOLE_ARG); | |
461 | + } | |
462 | + env_val = buf; | |
463 | + } else { | |
464 | + buf = NULL; | |
465 | + env_val = CONSOLE_ARG; | |
466 | + } | |
467 | + | |
468 | + setenv("bootargs", env_val); | |
469 | + debug("after silent fix-up: %s\n", env_val); | |
470 | + free(buf); | |
471 | +} | |
472 | +#endif /* CONFIG_SILENT_CONSOLE */ | |
473 | + | |
474 | +/** | |
475 | + * Execute selected states of the bootm command. | |
476 | + * | |
477 | + * Note the arguments to this state must be the first argument, Any 'bootm' | |
478 | + * or sub-command arguments must have already been taken. | |
479 | + * | |
480 | + * Note that if states contains more than one flag it MUST contain | |
481 | + * BOOTM_STATE_START, since this handles and consumes the command line args. | |
482 | + * | |
483 | + * Also note that aside from boot_os_fn functions and bootm_load_os no other | |
484 | + * functions we store the return value of in 'ret' may use a negative return | |
485 | + * value, without special handling. | |
486 | + * | |
487 | + * @param cmdtp Pointer to bootm command table entry | |
488 | + * @param flag Command flags (CMD_FLAG_...) | |
489 | + * @param argc Number of subcommand arguments (0 = no arguments) | |
490 | + * @param argv Arguments | |
491 | + * @param states Mask containing states to run (BOOTM_STATE_...) | |
492 | + * @param images Image header information | |
493 | + * @param boot_progress 1 to show boot progress, 0 to not do this | |
494 | + * @return 0 if ok, something else on error. Some errors will cause this | |
495 | + * function to perform a reboot! If states contains BOOTM_STATE_OS_GO | |
496 | + * then the intent is to boot an OS, so this function will not return | |
497 | + * unless the image type is standalone. | |
498 | + */ | |
499 | +int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], | |
500 | + int states, bootm_headers_t *images, int boot_progress) | |
501 | +{ | |
502 | + boot_os_fn *boot_fn; | |
503 | + ulong iflag = 0; | |
504 | + int ret = 0, need_boot_fn; | |
505 | + | |
506 | + images->state |= states; | |
507 | + | |
508 | + /* | |
509 | + * Work through the states and see how far we get. We stop on | |
510 | + * any error. | |
511 | + */ | |
512 | + if (states & BOOTM_STATE_START) | |
513 | + ret = bootm_start(cmdtp, flag, argc, argv); | |
514 | + | |
515 | + if (!ret && (states & BOOTM_STATE_FINDOS)) | |
516 | + ret = bootm_find_os(cmdtp, flag, argc, argv); | |
517 | + | |
518 | + if (!ret && (states & BOOTM_STATE_FINDOTHER)) { | |
519 | + ret = bootm_find_other(cmdtp, flag, argc, argv); | |
520 | + argc = 0; /* consume the args */ | |
521 | + } | |
522 | + | |
523 | + /* Load the OS */ | |
524 | + if (!ret && (states & BOOTM_STATE_LOADOS)) { | |
525 | + ulong load_end; | |
526 | + | |
527 | + iflag = bootm_disable_interrupts(); | |
528 | + ret = bootm_load_os(images, &load_end, 0); | |
529 | + if (ret == 0) | |
530 | + lmb_reserve(&images->lmb, images->os.load, | |
531 | + (load_end - images->os.load)); | |
532 | + else if (ret && ret != BOOTM_ERR_OVERLAP) | |
533 | + goto err; | |
534 | + else if (ret == BOOTM_ERR_OVERLAP) | |
535 | + ret = 0; | |
536 | +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) | |
537 | + if (images->os.os == IH_OS_LINUX) | |
538 | + fixup_silent_linux(); | |
539 | +#endif | |
540 | + } | |
541 | + | |
542 | + /* Relocate the ramdisk */ | |
543 | +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH | |
544 | + if (!ret && (states & BOOTM_STATE_RAMDISK)) { | |
545 | + ulong rd_len = images->rd_end - images->rd_start; | |
546 | + | |
547 | + ret = boot_ramdisk_high(&images->lmb, images->rd_start, | |
548 | + rd_len, &images->initrd_start, &images->initrd_end); | |
549 | + if (!ret) { | |
550 | + setenv_hex("initrd_start", images->initrd_start); | |
551 | + setenv_hex("initrd_end", images->initrd_end); | |
552 | + } | |
553 | + } | |
554 | +#endif | |
555 | +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) | |
556 | + if (!ret && (states & BOOTM_STATE_FDT)) { | |
557 | + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); | |
558 | + ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, | |
559 | + &images->ft_len); | |
560 | + } | |
561 | +#endif | |
562 | + | |
563 | + /* From now on, we need the OS boot function */ | |
564 | + if (ret) | |
565 | + return ret; | |
566 | + boot_fn = bootm_os_get_boot_func(images->os.os); | |
567 | + need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE | | |
568 | + BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP | | |
569 | + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO); | |
570 | + if (boot_fn == NULL && need_boot_fn) { | |
571 | + if (iflag) | |
572 | + enable_interrupts(); | |
573 | + printf("ERROR: booting os '%s' (%d) is not supported\n", | |
574 | + genimg_get_os_name(images->os.os), images->os.os); | |
575 | + bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); | |
576 | + return 1; | |
577 | + } | |
578 | + | |
579 | + /* Call various other states that are not generally used */ | |
580 | + if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) | |
581 | + ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); | |
582 | + if (!ret && (states & BOOTM_STATE_OS_BD_T)) | |
583 | + ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); | |
584 | + if (!ret && (states & BOOTM_STATE_OS_PREP)) | |
585 | + ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); | |
586 | + | |
587 | +#ifdef CONFIG_TRACE | |
588 | + /* Pretend to run the OS, then run a user command */ | |
589 | + if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { | |
590 | + char *cmd_list = getenv("fakegocmd"); | |
591 | + | |
592 | + ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, | |
593 | + images, boot_fn); | |
594 | + if (!ret && cmd_list) | |
595 | + ret = run_command_list(cmd_list, -1, flag); | |
596 | + } | |
597 | +#endif | |
598 | + | |
599 | + /* Check for unsupported subcommand. */ | |
600 | + if (ret) { | |
601 | + puts("subcommand not supported\n"); | |
602 | + return ret; | |
603 | + } | |
604 | + | |
605 | + /* Now run the OS! We hope this doesn't return */ | |
606 | + if (!ret && (states & BOOTM_STATE_OS_GO)) | |
607 | + ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, | |
608 | + images, boot_fn); | |
609 | + | |
610 | + /* Deal with any fallout */ | |
611 | +err: | |
612 | + if (iflag) | |
613 | + enable_interrupts(); | |
614 | + | |
615 | + if (ret == BOOTM_ERR_UNIMPLEMENTED) | |
616 | + bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); | |
617 | + else if (ret == BOOTM_ERR_RESET) | |
618 | + do_reset(cmdtp, flag, argc, argv); | |
619 | + | |
620 | + return ret; | |
621 | +} | |
622 | + | |
623 | +#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
624 | +/** | |
625 | + * image_get_kernel - verify legacy format kernel image | |
626 | + * @img_addr: in RAM address of the legacy format image to be verified | |
627 | + * @verify: data CRC verification flag | |
628 | + * | |
629 | + * image_get_kernel() verifies legacy image integrity and returns pointer to | |
630 | + * legacy image header if image verification was completed successfully. | |
631 | + * | |
632 | + * returns: | |
633 | + * pointer to a legacy image header if valid image was found | |
634 | + * otherwise return NULL | |
635 | + */ | |
636 | +static image_header_t *image_get_kernel(ulong img_addr, int verify) | |
637 | +{ | |
638 | + image_header_t *hdr = (image_header_t *)img_addr; | |
639 | + | |
640 | + if (!image_check_magic(hdr)) { | |
641 | + puts("Bad Magic Number\n"); | |
642 | + bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC); | |
643 | + return NULL; | |
644 | + } | |
645 | + bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER); | |
646 | + | |
647 | + if (!image_check_hcrc(hdr)) { | |
648 | + puts("Bad Header Checksum\n"); | |
649 | + bootstage_error(BOOTSTAGE_ID_CHECK_HEADER); | |
650 | + return NULL; | |
651 | + } | |
652 | + | |
653 | + bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM); | |
654 | + image_print_contents(hdr); | |
655 | + | |
656 | + if (verify) { | |
657 | + puts(" Verifying Checksum ... "); | |
658 | + if (!image_check_dcrc(hdr)) { | |
659 | + printf("Bad Data CRC\n"); | |
660 | + bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM); | |
661 | + return NULL; | |
662 | + } | |
663 | + puts("OK\n"); | |
664 | + } | |
665 | + bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH); | |
666 | + | |
667 | + if (!image_check_target_arch(hdr)) { | |
668 | + printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); | |
669 | + bootstage_error(BOOTSTAGE_ID_CHECK_ARCH); | |
670 | + return NULL; | |
671 | + } | |
672 | + return hdr; | |
673 | +} | |
674 | +#endif | |
675 | + | |
676 | +/** | |
677 | + * boot_get_kernel - find kernel image | |
678 | + * @os_data: pointer to a ulong variable, will hold os data start address | |
679 | + * @os_len: pointer to a ulong variable, will hold os data length | |
680 | + * | |
681 | + * boot_get_kernel() tries to find a kernel image, verifies its integrity | |
682 | + * and locates kernel data. | |
683 | + * | |
684 | + * returns: | |
685 | + * pointer to image header if valid image was found, plus kernel start | |
686 | + * address and length, otherwise NULL | |
687 | + */ | |
688 | +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, | |
689 | + char * const argv[], bootm_headers_t *images, | |
690 | + ulong *os_data, ulong *os_len) | |
691 | +{ | |
692 | +#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
693 | + image_header_t *hdr; | |
694 | +#endif | |
695 | + ulong img_addr; | |
696 | + const void *buf; | |
697 | +#if defined(CONFIG_FIT) | |
698 | + const char *fit_uname_config = NULL; | |
699 | + const char *fit_uname_kernel = NULL; | |
700 | + int os_noffset; | |
701 | +#endif | |
702 | + | |
703 | + /* find out kernel image address */ | |
704 | + if (argc < 1) { | |
705 | + img_addr = load_addr; | |
706 | + debug("* kernel: default image load address = 0x%08lx\n", | |
707 | + load_addr); | |
708 | +#if defined(CONFIG_FIT) | |
709 | + } else if (fit_parse_conf(argv[0], load_addr, &img_addr, | |
710 | + &fit_uname_config)) { | |
711 | + debug("* kernel: config '%s' from image at 0x%08lx\n", | |
712 | + fit_uname_config, img_addr); | |
713 | + } else if (fit_parse_subimage(argv[0], load_addr, &img_addr, | |
714 | + &fit_uname_kernel)) { | |
715 | + debug("* kernel: subimage '%s' from image at 0x%08lx\n", | |
716 | + fit_uname_kernel, img_addr); | |
717 | +#endif | |
718 | + } else { | |
719 | + img_addr = simple_strtoul(argv[0], NULL, 16); | |
720 | + debug("* kernel: cmdline image address = 0x%08lx\n", | |
721 | + img_addr); | |
722 | + } | |
723 | + | |
724 | + bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); | |
725 | + | |
726 | + /* copy from dataflash if needed */ | |
727 | + img_addr = genimg_get_image(img_addr); | |
728 | + | |
729 | + /* check image type, for FIT images get FIT kernel node */ | |
730 | + *os_data = *os_len = 0; | |
731 | + buf = map_sysmem(img_addr, 0); | |
732 | + switch (genimg_get_format(buf)) { | |
733 | +#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
734 | + case IMAGE_FORMAT_LEGACY: | |
735 | + printf("## Booting kernel from Legacy Image at %08lx ...\n", | |
736 | + img_addr); | |
737 | + hdr = image_get_kernel(img_addr, images->verify); | |
738 | + if (!hdr) | |
739 | + return NULL; | |
740 | + bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); | |
741 | + | |
742 | + /* get os_data and os_len */ | |
743 | + switch (image_get_type(hdr)) { | |
744 | + case IH_TYPE_KERNEL: | |
745 | + case IH_TYPE_KERNEL_NOLOAD: | |
746 | + *os_data = image_get_data(hdr); | |
747 | + *os_len = image_get_data_size(hdr); | |
748 | + break; | |
749 | + case IH_TYPE_MULTI: | |
750 | + image_multi_getimg(hdr, 0, os_data, os_len); | |
751 | + break; | |
752 | + case IH_TYPE_STANDALONE: | |
753 | + *os_data = image_get_data(hdr); | |
754 | + *os_len = image_get_data_size(hdr); | |
755 | + break; | |
756 | + default: | |
757 | + printf("Wrong Image Type for %s command\n", | |
758 | + cmdtp->name); | |
759 | + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); | |
760 | + return NULL; | |
761 | + } | |
762 | + | |
763 | + /* | |
764 | + * copy image header to allow for image overwrites during | |
765 | + * kernel decompression. | |
766 | + */ | |
767 | + memmove(&images->legacy_hdr_os_copy, hdr, | |
768 | + sizeof(image_header_t)); | |
769 | + | |
770 | + /* save pointer to image header */ | |
771 | + images->legacy_hdr_os = hdr; | |
772 | + | |
773 | + images->legacy_hdr_valid = 1; | |
774 | + bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); | |
775 | + break; | |
776 | +#endif | |
777 | +#if defined(CONFIG_FIT) | |
778 | + case IMAGE_FORMAT_FIT: | |
779 | + os_noffset = fit_image_load(images, FIT_KERNEL_PROP, | |
780 | + img_addr, | |
781 | + &fit_uname_kernel, &fit_uname_config, | |
782 | + IH_ARCH_DEFAULT, IH_TYPE_KERNEL, | |
783 | + BOOTSTAGE_ID_FIT_KERNEL_START, | |
784 | + FIT_LOAD_IGNORED, os_data, os_len); | |
785 | + if (os_noffset < 0) | |
786 | + return NULL; | |
787 | + | |
788 | + images->fit_hdr_os = map_sysmem(img_addr, 0); | |
789 | + images->fit_uname_os = fit_uname_kernel; | |
790 | + images->fit_uname_cfg = fit_uname_config; | |
791 | + images->fit_noffset_os = os_noffset; | |
792 | + break; | |
793 | +#endif | |
794 | +#ifdef CONFIG_ANDROID_BOOT_IMAGE | |
795 | + case IMAGE_FORMAT_ANDROID: | |
796 | + printf("## Booting Android Image at 0x%08lx ...\n", img_addr); | |
797 | + if (android_image_get_kernel((void *)img_addr, images->verify, | |
798 | + os_data, os_len)) | |
799 | + return NULL; | |
800 | + break; | |
801 | +#endif | |
802 | + default: | |
803 | + printf("Wrong Image Format for %s command\n", cmdtp->name); | |
804 | + bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); | |
805 | + return NULL; | |
806 | + } | |
807 | + | |
808 | + debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", | |
809 | + *os_data, *os_len, *os_len); | |
810 | + | |
811 | + return buf; | |
812 | +} |
1 | +/* | |
2 | + * (C) Copyright 2000-2009 | |
3 | + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <bootm.h> | |
10 | +#include <fdt_support.h> | |
11 | +#include <libfdt.h> | |
12 | +#include <malloc.h> | |
13 | +#include <vxworks.h> | |
14 | + | |
15 | +DECLARE_GLOBAL_DATA_PTR; | |
16 | + | |
17 | +static int do_bootm_standalone(int flag, int argc, char * const argv[], | |
18 | + bootm_headers_t *images) | |
19 | +{ | |
20 | + char *s; | |
21 | + int (*appl)(int, char *const[]); | |
22 | + | |
23 | + /* Don't start if "autostart" is set to "no" */ | |
24 | + s = getenv("autostart"); | |
25 | + if ((s != NULL) && !strcmp(s, "no")) { | |
26 | + setenv_hex("filesize", images->os.image_len); | |
27 | + return 0; | |
28 | + } | |
29 | + appl = (int (*)(int, char * const []))images->ep; | |
30 | + appl(argc, argv); | |
31 | + return 0; | |
32 | +} | |
33 | + | |
34 | +/*******************************************************************/ | |
35 | +/* OS booting routines */ | |
36 | +/*******************************************************************/ | |
37 | + | |
38 | +#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9) | |
39 | +static void copy_args(char *dest, int argc, char * const argv[], char delim) | |
40 | +{ | |
41 | + int i; | |
42 | + | |
43 | + for (i = 0; i < argc; i++) { | |
44 | + if (i > 0) | |
45 | + *dest++ = delim; | |
46 | + strcpy(dest, argv[i]); | |
47 | + dest += strlen(argv[i]); | |
48 | + } | |
49 | +} | |
50 | +#endif | |
51 | + | |
52 | +#ifdef CONFIG_BOOTM_NETBSD | |
53 | +static int do_bootm_netbsd(int flag, int argc, char * const argv[], | |
54 | + bootm_headers_t *images) | |
55 | +{ | |
56 | + void (*loader)(bd_t *, image_header_t *, char *, char *); | |
57 | + image_header_t *os_hdr, *hdr; | |
58 | + ulong kernel_data, kernel_len; | |
59 | + char *consdev; | |
60 | + char *cmdline; | |
61 | + | |
62 | + if (flag != BOOTM_STATE_OS_GO) | |
63 | + return 0; | |
64 | + | |
65 | +#if defined(CONFIG_FIT) | |
66 | + if (!images->legacy_hdr_valid) { | |
67 | + fit_unsupported_reset("NetBSD"); | |
68 | + return 1; | |
69 | + } | |
70 | +#endif | |
71 | + hdr = images->legacy_hdr_os; | |
72 | + | |
73 | + /* | |
74 | + * Booting a (NetBSD) kernel image | |
75 | + * | |
76 | + * This process is pretty similar to a standalone application: | |
77 | + * The (first part of an multi-) image must be a stage-2 loader, | |
78 | + * which in turn is responsible for loading & invoking the actual | |
79 | + * kernel. The only differences are the parameters being passed: | |
80 | + * besides the board info strucure, the loader expects a command | |
81 | + * line, the name of the console device, and (optionally) the | |
82 | + * address of the original image header. | |
83 | + */ | |
84 | + os_hdr = NULL; | |
85 | + if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { | |
86 | + image_multi_getimg(hdr, 1, &kernel_data, &kernel_len); | |
87 | + if (kernel_len) | |
88 | + os_hdr = hdr; | |
89 | + } | |
90 | + | |
91 | + consdev = ""; | |
92 | +#if defined(CONFIG_8xx_CONS_SMC1) | |
93 | + consdev = "smc1"; | |
94 | +#elif defined(CONFIG_8xx_CONS_SMC2) | |
95 | + consdev = "smc2"; | |
96 | +#elif defined(CONFIG_8xx_CONS_SCC2) | |
97 | + consdev = "scc2"; | |
98 | +#elif defined(CONFIG_8xx_CONS_SCC3) | |
99 | + consdev = "scc3"; | |
100 | +#endif | |
101 | + | |
102 | + if (argc > 0) { | |
103 | + ulong len; | |
104 | + int i; | |
105 | + | |
106 | + for (i = 0, len = 0; i < argc; i += 1) | |
107 | + len += strlen(argv[i]) + 1; | |
108 | + cmdline = malloc(len); | |
109 | + copy_args(cmdline, argc, argv, ' '); | |
110 | + } else { | |
111 | + cmdline = getenv("bootargs"); | |
112 | + if (cmdline == NULL) | |
113 | + cmdline = ""; | |
114 | + } | |
115 | + | |
116 | + loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep; | |
117 | + | |
118 | + printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", | |
119 | + (ulong)loader); | |
120 | + | |
121 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
122 | + | |
123 | + /* | |
124 | + * NetBSD Stage-2 Loader Parameters: | |
125 | + * arg[0]: pointer to board info data | |
126 | + * arg[1]: image load address | |
127 | + * arg[2]: char pointer to the console device to use | |
128 | + * arg[3]: char pointer to the boot arguments | |
129 | + */ | |
130 | + (*loader)(gd->bd, os_hdr, consdev, cmdline); | |
131 | + | |
132 | + return 1; | |
133 | +} | |
134 | +#endif /* CONFIG_BOOTM_NETBSD*/ | |
135 | + | |
136 | +#ifdef CONFIG_LYNXKDI | |
137 | +static int do_bootm_lynxkdi(int flag, int argc, char * const argv[], | |
138 | + bootm_headers_t *images) | |
139 | +{ | |
140 | + image_header_t *hdr = &images->legacy_hdr_os_copy; | |
141 | + | |
142 | + if (flag != BOOTM_STATE_OS_GO) | |
143 | + return 0; | |
144 | + | |
145 | +#if defined(CONFIG_FIT) | |
146 | + if (!images->legacy_hdr_valid) { | |
147 | + fit_unsupported_reset("Lynx"); | |
148 | + return 1; | |
149 | + } | |
150 | +#endif | |
151 | + | |
152 | + lynxkdi_boot((image_header_t *)hdr); | |
153 | + | |
154 | + return 1; | |
155 | +} | |
156 | +#endif /* CONFIG_LYNXKDI */ | |
157 | + | |
158 | +#ifdef CONFIG_BOOTM_RTEMS | |
159 | +static int do_bootm_rtems(int flag, int argc, char * const argv[], | |
160 | + bootm_headers_t *images) | |
161 | +{ | |
162 | + void (*entry_point)(bd_t *); | |
163 | + | |
164 | + if (flag != BOOTM_STATE_OS_GO) | |
165 | + return 0; | |
166 | + | |
167 | +#if defined(CONFIG_FIT) | |
168 | + if (!images->legacy_hdr_valid) { | |
169 | + fit_unsupported_reset("RTEMS"); | |
170 | + return 1; | |
171 | + } | |
172 | +#endif | |
173 | + | |
174 | + entry_point = (void (*)(bd_t *))images->ep; | |
175 | + | |
176 | + printf("## Transferring control to RTEMS (at address %08lx) ...\n", | |
177 | + (ulong)entry_point); | |
178 | + | |
179 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
180 | + | |
181 | + /* | |
182 | + * RTEMS Parameters: | |
183 | + * r3: ptr to board info data | |
184 | + */ | |
185 | + (*entry_point)(gd->bd); | |
186 | + | |
187 | + return 1; | |
188 | +} | |
189 | +#endif /* CONFIG_BOOTM_RTEMS */ | |
190 | + | |
191 | +#if defined(CONFIG_BOOTM_OSE) | |
192 | +static int do_bootm_ose(int flag, int argc, char * const argv[], | |
193 | + bootm_headers_t *images) | |
194 | +{ | |
195 | + void (*entry_point)(void); | |
196 | + | |
197 | + if (flag != BOOTM_STATE_OS_GO) | |
198 | + return 0; | |
199 | + | |
200 | +#if defined(CONFIG_FIT) | |
201 | + if (!images->legacy_hdr_valid) { | |
202 | + fit_unsupported_reset("OSE"); | |
203 | + return 1; | |
204 | + } | |
205 | +#endif | |
206 | + | |
207 | + entry_point = (void (*)(void))images->ep; | |
208 | + | |
209 | + printf("## Transferring control to OSE (at address %08lx) ...\n", | |
210 | + (ulong)entry_point); | |
211 | + | |
212 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
213 | + | |
214 | + /* | |
215 | + * OSE Parameters: | |
216 | + * None | |
217 | + */ | |
218 | + (*entry_point)(); | |
219 | + | |
220 | + return 1; | |
221 | +} | |
222 | +#endif /* CONFIG_BOOTM_OSE */ | |
223 | + | |
224 | +#if defined(CONFIG_BOOTM_PLAN9) | |
225 | +static int do_bootm_plan9(int flag, int argc, char * const argv[], | |
226 | + bootm_headers_t *images) | |
227 | +{ | |
228 | + void (*entry_point)(void); | |
229 | + char *s; | |
230 | + | |
231 | + if (flag != BOOTM_STATE_OS_GO) | |
232 | + return 0; | |
233 | + | |
234 | +#if defined(CONFIG_FIT) | |
235 | + if (!images->legacy_hdr_valid) { | |
236 | + fit_unsupported_reset("Plan 9"); | |
237 | + return 1; | |
238 | + } | |
239 | +#endif | |
240 | + | |
241 | + /* See README.plan9 */ | |
242 | + s = getenv("confaddr"); | |
243 | + if (s != NULL) { | |
244 | + char *confaddr = (char *)simple_strtoul(s, NULL, 16); | |
245 | + | |
246 | + if (argc > 0) { | |
247 | + copy_args(confaddr, argc, argv, '\n'); | |
248 | + } else { | |
249 | + s = getenv("bootargs"); | |
250 | + if (s != NULL) | |
251 | + strcpy(confaddr, s); | |
252 | + } | |
253 | + } | |
254 | + | |
255 | + entry_point = (void (*)(void))images->ep; | |
256 | + | |
257 | + printf("## Transferring control to Plan 9 (at address %08lx) ...\n", | |
258 | + (ulong)entry_point); | |
259 | + | |
260 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
261 | + | |
262 | + /* | |
263 | + * Plan 9 Parameters: | |
264 | + * None | |
265 | + */ | |
266 | + (*entry_point)(); | |
267 | + | |
268 | + return 1; | |
269 | +} | |
270 | +#endif /* CONFIG_BOOTM_PLAN9 */ | |
271 | + | |
272 | +#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
273 | + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
274 | + | |
275 | +void do_bootvx_fdt(bootm_headers_t *images) | |
276 | +{ | |
277 | +#if defined(CONFIG_OF_LIBFDT) | |
278 | + int ret; | |
279 | + char *bootline; | |
280 | + ulong of_size = images->ft_len; | |
281 | + char **of_flat_tree = &images->ft_addr; | |
282 | + struct lmb *lmb = &images->lmb; | |
283 | + | |
284 | + if (*of_flat_tree) { | |
285 | + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); | |
286 | + | |
287 | + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); | |
288 | + if (ret) | |
289 | + return; | |
290 | + | |
291 | + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); | |
292 | + if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { | |
293 | + bootline = getenv("bootargs"); | |
294 | + if (bootline) { | |
295 | + ret = fdt_find_and_setprop(*of_flat_tree, | |
296 | + "/chosen", "bootargs", | |
297 | + bootline, | |
298 | + strlen(bootline) + 1, 1); | |
299 | + if (ret < 0) { | |
300 | + printf("## ERROR: %s : %s\n", __func__, | |
301 | + fdt_strerror(ret)); | |
302 | + return; | |
303 | + } | |
304 | + } | |
305 | + } else { | |
306 | + printf("## ERROR: %s : %s\n", __func__, | |
307 | + fdt_strerror(ret)); | |
308 | + return; | |
309 | + } | |
310 | + } | |
311 | +#endif | |
312 | + | |
313 | + boot_prep_vxworks(images); | |
314 | + | |
315 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
316 | + | |
317 | +#if defined(CONFIG_OF_LIBFDT) | |
318 | + printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n", | |
319 | + (ulong)images->ep, (ulong)*of_flat_tree); | |
320 | +#else | |
321 | + printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); | |
322 | +#endif | |
323 | + | |
324 | + boot_jump_vxworks(images); | |
325 | + | |
326 | + puts("## vxWorks terminated\n"); | |
327 | +} | |
328 | + | |
329 | +static int do_bootm_vxworks(int flag, int argc, char * const argv[], | |
330 | + bootm_headers_t *images) | |
331 | +{ | |
332 | + if (flag != BOOTM_STATE_OS_GO) | |
333 | + return 0; | |
334 | + | |
335 | +#if defined(CONFIG_FIT) | |
336 | + if (!images->legacy_hdr_valid) { | |
337 | + fit_unsupported_reset("VxWorks"); | |
338 | + return 1; | |
339 | + } | |
340 | +#endif | |
341 | + | |
342 | + do_bootvx_fdt(images); | |
343 | + | |
344 | + return 1; | |
345 | +} | |
346 | +#endif | |
347 | + | |
348 | +#if defined(CONFIG_CMD_ELF) | |
349 | +static int do_bootm_qnxelf(int flag, int argc, char * const argv[], | |
350 | + bootm_headers_t *images) | |
351 | +{ | |
352 | + char *local_args[2]; | |
353 | + char str[16]; | |
354 | + | |
355 | + if (flag != BOOTM_STATE_OS_GO) | |
356 | + return 0; | |
357 | + | |
358 | +#if defined(CONFIG_FIT) | |
359 | + if (!images->legacy_hdr_valid) { | |
360 | + fit_unsupported_reset("QNX"); | |
361 | + return 1; | |
362 | + } | |
363 | +#endif | |
364 | + | |
365 | + sprintf(str, "%lx", images->ep); /* write entry-point into string */ | |
366 | + local_args[0] = argv[0]; | |
367 | + local_args[1] = str; /* and provide it via the arguments */ | |
368 | + do_bootelf(NULL, 0, 2, local_args); | |
369 | + | |
370 | + return 1; | |
371 | +} | |
372 | +#endif | |
373 | + | |
374 | +#ifdef CONFIG_INTEGRITY | |
375 | +static int do_bootm_integrity(int flag, int argc, char * const argv[], | |
376 | + bootm_headers_t *images) | |
377 | +{ | |
378 | + void (*entry_point)(void); | |
379 | + | |
380 | + if (flag != BOOTM_STATE_OS_GO) | |
381 | + return 0; | |
382 | + | |
383 | +#if defined(CONFIG_FIT) | |
384 | + if (!images->legacy_hdr_valid) { | |
385 | + fit_unsupported_reset("INTEGRITY"); | |
386 | + return 1; | |
387 | + } | |
388 | +#endif | |
389 | + | |
390 | + entry_point = (void (*)(void))images->ep; | |
391 | + | |
392 | + printf("## Transferring control to INTEGRITY (at address %08lx) ...\n", | |
393 | + (ulong)entry_point); | |
394 | + | |
395 | + bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
396 | + | |
397 | + /* | |
398 | + * INTEGRITY Parameters: | |
399 | + * None | |
400 | + */ | |
401 | + (*entry_point)(); | |
402 | + | |
403 | + return 1; | |
404 | +} | |
405 | +#endif | |
406 | + | |
407 | +static boot_os_fn *boot_os[] = { | |
408 | + [IH_OS_U_BOOT] = do_bootm_standalone, | |
409 | +#ifdef CONFIG_BOOTM_LINUX | |
410 | + [IH_OS_LINUX] = do_bootm_linux, | |
411 | +#endif | |
412 | +#ifdef CONFIG_BOOTM_NETBSD | |
413 | + [IH_OS_NETBSD] = do_bootm_netbsd, | |
414 | +#endif | |
415 | +#ifdef CONFIG_LYNXKDI | |
416 | + [IH_OS_LYNXOS] = do_bootm_lynxkdi, | |
417 | +#endif | |
418 | +#ifdef CONFIG_BOOTM_RTEMS | |
419 | + [IH_OS_RTEMS] = do_bootm_rtems, | |
420 | +#endif | |
421 | +#if defined(CONFIG_BOOTM_OSE) | |
422 | + [IH_OS_OSE] = do_bootm_ose, | |
423 | +#endif | |
424 | +#if defined(CONFIG_BOOTM_PLAN9) | |
425 | + [IH_OS_PLAN9] = do_bootm_plan9, | |
426 | +#endif | |
427 | +#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
428 | + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
429 | + [IH_OS_VXWORKS] = do_bootm_vxworks, | |
430 | +#endif | |
431 | +#if defined(CONFIG_CMD_ELF) | |
432 | + [IH_OS_QNX] = do_bootm_qnxelf, | |
433 | +#endif | |
434 | +#ifdef CONFIG_INTEGRITY | |
435 | + [IH_OS_INTEGRITY] = do_bootm_integrity, | |
436 | +#endif | |
437 | +}; | |
438 | + | |
439 | +/* Allow for arch specific config before we boot */ | |
440 | +static void __arch_preboot_os(void) | |
441 | +{ | |
442 | + /* please define platform specific arch_preboot_os() */ | |
443 | +} | |
444 | +void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os"))); | |
445 | + | |
446 | +int boot_selected_os(int argc, char * const argv[], int state, | |
447 | + bootm_headers_t *images, boot_os_fn *boot_fn) | |
448 | +{ | |
449 | + arch_preboot_os(); | |
450 | + boot_fn(state, argc, argv, images); | |
451 | + | |
452 | + /* Stand-alone may return when 'autostart' is 'no' */ | |
453 | + if (images->os.type == IH_TYPE_STANDALONE || | |
454 | + state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ | |
455 | + return 0; | |
456 | + bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); | |
457 | +#ifdef DEBUG | |
458 | + puts("\n## Control returned to monitor - resetting...\n"); | |
459 | +#endif | |
460 | + return BOOTM_ERR_RESET; | |
461 | +} | |
462 | + | |
463 | +boot_os_fn *bootm_os_get_boot_func(int os) | |
464 | +{ | |
465 | +#ifdef CONFIG_NEEDS_MANUAL_RELOC | |
466 | + static bool relocated; | |
467 | + | |
468 | + if (!relocated) { | |
469 | + int i; | |
470 | + | |
471 | + /* relocate boot function table */ | |
472 | + for (i = 0; i < ARRAY_SIZE(boot_os); i++) | |
473 | + if (boot_os[i] != NULL) | |
474 | + boot_os[i] += gd->reloc_off; | |
475 | + | |
476 | + relocated = true; | |
477 | + } | |
478 | +#endif | |
479 | + return boot_os[os]; | |
480 | +} |
... | ... | @@ -5,58 +5,25 @@ |
5 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6 | 6 | */ |
7 | 7 | |
8 | - | |
9 | 8 | /* |
10 | 9 | * Boot support |
11 | 10 | */ |
12 | 11 | #include <common.h> |
13 | -#include <watchdog.h> | |
12 | +#include <bootm.h> | |
14 | 13 | #include <command.h> |
15 | -#include <image.h> | |
16 | -#include <malloc.h> | |
17 | -#include <u-boot/zlib.h> | |
18 | -#include <bzlib.h> | |
19 | 14 | #include <environment.h> |
15 | +#include <image.h> | |
20 | 16 | #include <lmb.h> |
21 | -#include <linux/ctype.h> | |
17 | +#include <malloc.h> | |
18 | +#include <nand.h> | |
22 | 19 | #include <asm/byteorder.h> |
23 | -#include <asm/io.h> | |
24 | 20 | #include <linux/compiler.h> |
21 | +#include <linux/ctype.h> | |
22 | +#include <linux/err.h> | |
23 | +#include <u-boot/zlib.h> | |
25 | 24 | |
26 | -#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
27 | - (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
28 | -#include <vxworks.h> | |
29 | -#endif | |
30 | - | |
31 | -#if defined(CONFIG_CMD_USB) | |
32 | -#include <usb.h> | |
33 | -#endif | |
34 | - | |
35 | -#if defined(CONFIG_OF_LIBFDT) | |
36 | -#include <libfdt.h> | |
37 | -#include <fdt_support.h> | |
38 | -#endif | |
39 | - | |
40 | -#ifdef CONFIG_LZMA | |
41 | -#include <lzma/LzmaTypes.h> | |
42 | -#include <lzma/LzmaDec.h> | |
43 | -#include <lzma/LzmaTools.h> | |
44 | -#endif /* CONFIG_LZMA */ | |
45 | - | |
46 | -#ifdef CONFIG_LZO | |
47 | -#include <linux/lzo.h> | |
48 | -#endif /* CONFIG_LZO */ | |
49 | - | |
50 | 25 | DECLARE_GLOBAL_DATA_PTR; |
51 | 26 | |
52 | -#ifndef CONFIG_SYS_BOOTM_LEN | |
53 | -#define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ | |
54 | -#endif | |
55 | - | |
56 | -#ifdef CONFIG_BZIP2 | |
57 | -extern void bz_internal_error(int); | |
58 | -#endif | |
59 | - | |
60 | 27 | #if defined(CONFIG_CMD_IMI) |
61 | 28 | static int image_info(unsigned long addr); |
62 | 29 | #endif |
63 | 30 | |
... | ... | @@ -71,465 +38,8 @@ |
71 | 38 | static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); |
72 | 39 | #endif |
73 | 40 | |
74 | -#include <linux/err.h> | |
75 | -#include <nand.h> | |
76 | - | |
77 | -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) | |
78 | -static void fixup_silent_linux(void); | |
79 | -#endif | |
80 | - | |
81 | -static int do_bootm_standalone(int flag, int argc, char * const argv[], | |
82 | - bootm_headers_t *images); | |
83 | - | |
84 | -static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, | |
85 | - char * const argv[], bootm_headers_t *images, | |
86 | - ulong *os_data, ulong *os_len); | |
87 | - | |
88 | -/* | |
89 | - * Continue booting an OS image; caller already has: | |
90 | - * - copied image header to global variable `header' | |
91 | - * - checked header magic number, checksums (both header & image), | |
92 | - * - verified image architecture (PPC) and type (KERNEL or MULTI), | |
93 | - * - loaded (first part of) image to header load address, | |
94 | - * - disabled interrupts. | |
95 | - * | |
96 | - * @flag: Flags indicating what to do (BOOTM_STATE_...) | |
97 | - * @argc: Number of arguments. Note that the arguments are shifted down | |
98 | - * so that 0 is the first argument not processed by U-Boot, and | |
99 | - * argc is adjusted accordingly. This avoids confusion as to how | |
100 | - * many arguments are available for the OS. | |
101 | - * @images: Pointers to os/initrd/fdt | |
102 | - * @return 1 on error. On success the OS boots so this function does | |
103 | - * not return. | |
104 | - */ | |
105 | -typedef int boot_os_fn(int flag, int argc, char * const argv[], | |
106 | - bootm_headers_t *images); | |
107 | - | |
108 | -#ifdef CONFIG_BOOTM_LINUX | |
109 | -extern boot_os_fn do_bootm_linux; | |
110 | -#endif | |
111 | -#ifdef CONFIG_BOOTM_NETBSD | |
112 | -static boot_os_fn do_bootm_netbsd; | |
113 | -#endif | |
114 | -#if defined(CONFIG_LYNXKDI) | |
115 | -static boot_os_fn do_bootm_lynxkdi; | |
116 | -extern void lynxkdi_boot(image_header_t *); | |
117 | -#endif | |
118 | -#ifdef CONFIG_BOOTM_RTEMS | |
119 | -static boot_os_fn do_bootm_rtems; | |
120 | -#endif | |
121 | -#if defined(CONFIG_BOOTM_OSE) | |
122 | -static boot_os_fn do_bootm_ose; | |
123 | -#endif | |
124 | -#if defined(CONFIG_BOOTM_PLAN9) | |
125 | -static boot_os_fn do_bootm_plan9; | |
126 | -#endif | |
127 | -#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
128 | - (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
129 | -static boot_os_fn do_bootm_vxworks; | |
130 | -#endif | |
131 | -#if defined(CONFIG_CMD_ELF) | |
132 | -static boot_os_fn do_bootm_qnxelf; | |
133 | -int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); | |
134 | -int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); | |
135 | -#endif | |
136 | -#if defined(CONFIG_INTEGRITY) | |
137 | -static boot_os_fn do_bootm_integrity; | |
138 | -#endif | |
139 | - | |
140 | -static boot_os_fn *boot_os[] = { | |
141 | - [IH_OS_U_BOOT] = do_bootm_standalone, | |
142 | -#ifdef CONFIG_BOOTM_LINUX | |
143 | - [IH_OS_LINUX] = do_bootm_linux, | |
144 | -#endif | |
145 | -#ifdef CONFIG_BOOTM_NETBSD | |
146 | - [IH_OS_NETBSD] = do_bootm_netbsd, | |
147 | -#endif | |
148 | -#ifdef CONFIG_LYNXKDI | |
149 | - [IH_OS_LYNXOS] = do_bootm_lynxkdi, | |
150 | -#endif | |
151 | -#ifdef CONFIG_BOOTM_RTEMS | |
152 | - [IH_OS_RTEMS] = do_bootm_rtems, | |
153 | -#endif | |
154 | -#if defined(CONFIG_BOOTM_OSE) | |
155 | - [IH_OS_OSE] = do_bootm_ose, | |
156 | -#endif | |
157 | -#if defined(CONFIG_BOOTM_PLAN9) | |
158 | - [IH_OS_PLAN9] = do_bootm_plan9, | |
159 | -#endif | |
160 | -#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
161 | - (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
162 | - [IH_OS_VXWORKS] = do_bootm_vxworks, | |
163 | -#endif | |
164 | -#if defined(CONFIG_CMD_ELF) | |
165 | - [IH_OS_QNX] = do_bootm_qnxelf, | |
166 | -#endif | |
167 | -#ifdef CONFIG_INTEGRITY | |
168 | - [IH_OS_INTEGRITY] = do_bootm_integrity, | |
169 | -#endif | |
170 | -}; | |
171 | - | |
172 | 41 | bootm_headers_t images; /* pointers to os/initrd/fdt images */ |
173 | 42 | |
174 | -/* Allow for arch specific config before we boot */ | |
175 | -static void __arch_preboot_os(void) | |
176 | -{ | |
177 | - /* please define platform specific arch_preboot_os() */ | |
178 | -} | |
179 | -void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os"))); | |
180 | - | |
181 | -#define IH_INITRD_ARCH IH_ARCH_DEFAULT | |
182 | - | |
183 | -#ifdef CONFIG_LMB | |
184 | -static void boot_start_lmb(bootm_headers_t *images) | |
185 | -{ | |
186 | - ulong mem_start; | |
187 | - phys_size_t mem_size; | |
188 | - | |
189 | - lmb_init(&images->lmb); | |
190 | - | |
191 | - mem_start = getenv_bootm_low(); | |
192 | - mem_size = getenv_bootm_size(); | |
193 | - | |
194 | - lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); | |
195 | - | |
196 | - arch_lmb_reserve(&images->lmb); | |
197 | - board_lmb_reserve(&images->lmb); | |
198 | -} | |
199 | -#else | |
200 | -#define lmb_reserve(lmb, base, size) | |
201 | -static inline void boot_start_lmb(bootm_headers_t *images) { } | |
202 | -#endif | |
203 | - | |
204 | -static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
205 | -{ | |
206 | - memset((void *)&images, 0, sizeof(images)); | |
207 | - images.verify = getenv_yesno("verify"); | |
208 | - | |
209 | - boot_start_lmb(&images); | |
210 | - | |
211 | - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); | |
212 | - images.state = BOOTM_STATE_START; | |
213 | - | |
214 | - return 0; | |
215 | -} | |
216 | - | |
217 | -static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, | |
218 | - char * const argv[]) | |
219 | -{ | |
220 | - const void *os_hdr; | |
221 | - bool ep_found = false; | |
222 | - | |
223 | - /* get kernel image header, start address and length */ | |
224 | - os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, | |
225 | - &images, &images.os.image_start, &images.os.image_len); | |
226 | - if (images.os.image_len == 0) { | |
227 | - puts("ERROR: can't get kernel image!\n"); | |
228 | - return 1; | |
229 | - } | |
230 | - | |
231 | - /* get image parameters */ | |
232 | - switch (genimg_get_format(os_hdr)) { | |
233 | -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
234 | - case IMAGE_FORMAT_LEGACY: | |
235 | - images.os.type = image_get_type(os_hdr); | |
236 | - images.os.comp = image_get_comp(os_hdr); | |
237 | - images.os.os = image_get_os(os_hdr); | |
238 | - | |
239 | - images.os.end = image_get_image_end(os_hdr); | |
240 | - images.os.load = image_get_load(os_hdr); | |
241 | - break; | |
242 | -#endif | |
243 | -#if defined(CONFIG_FIT) | |
244 | - case IMAGE_FORMAT_FIT: | |
245 | - if (fit_image_get_type(images.fit_hdr_os, | |
246 | - images.fit_noffset_os, &images.os.type)) { | |
247 | - puts("Can't get image type!\n"); | |
248 | - bootstage_error(BOOTSTAGE_ID_FIT_TYPE); | |
249 | - return 1; | |
250 | - } | |
251 | - | |
252 | - if (fit_image_get_comp(images.fit_hdr_os, | |
253 | - images.fit_noffset_os, &images.os.comp)) { | |
254 | - puts("Can't get image compression!\n"); | |
255 | - bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); | |
256 | - return 1; | |
257 | - } | |
258 | - | |
259 | - if (fit_image_get_os(images.fit_hdr_os, | |
260 | - images.fit_noffset_os, &images.os.os)) { | |
261 | - puts("Can't get image OS!\n"); | |
262 | - bootstage_error(BOOTSTAGE_ID_FIT_OS); | |
263 | - return 1; | |
264 | - } | |
265 | - | |
266 | - images.os.end = fit_get_end(images.fit_hdr_os); | |
267 | - | |
268 | - if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, | |
269 | - &images.os.load)) { | |
270 | - puts("Can't get image load address!\n"); | |
271 | - bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); | |
272 | - return 1; | |
273 | - } | |
274 | - break; | |
275 | -#endif | |
276 | -#ifdef CONFIG_ANDROID_BOOT_IMAGE | |
277 | - case IMAGE_FORMAT_ANDROID: | |
278 | - images.os.type = IH_TYPE_KERNEL; | |
279 | - images.os.comp = IH_COMP_NONE; | |
280 | - images.os.os = IH_OS_LINUX; | |
281 | - images.ep = images.os.load; | |
282 | - ep_found = true; | |
283 | - | |
284 | - images.os.end = android_image_get_end(os_hdr); | |
285 | - images.os.load = android_image_get_kload(os_hdr); | |
286 | - break; | |
287 | -#endif | |
288 | - default: | |
289 | - puts("ERROR: unknown image format type!\n"); | |
290 | - return 1; | |
291 | - } | |
292 | - | |
293 | - /* find kernel entry point */ | |
294 | - if (images.legacy_hdr_valid) { | |
295 | - images.ep = image_get_ep(&images.legacy_hdr_os_copy); | |
296 | -#if defined(CONFIG_FIT) | |
297 | - } else if (images.fit_uname_os) { | |
298 | - int ret; | |
299 | - | |
300 | - ret = fit_image_get_entry(images.fit_hdr_os, | |
301 | - images.fit_noffset_os, &images.ep); | |
302 | - if (ret) { | |
303 | - puts("Can't get entry point property!\n"); | |
304 | - return 1; | |
305 | - } | |
306 | -#endif | |
307 | - } else if (!ep_found) { | |
308 | - puts("Could not find kernel entry point!\n"); | |
309 | - return 1; | |
310 | - } | |
311 | - | |
312 | - if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { | |
313 | - images.os.load = images.os.image_start; | |
314 | - images.ep += images.os.load; | |
315 | - } | |
316 | - | |
317 | - images.os.start = (ulong)os_hdr; | |
318 | - | |
319 | - return 0; | |
320 | -} | |
321 | - | |
322 | -static int bootm_find_ramdisk(int flag, int argc, char * const argv[]) | |
323 | -{ | |
324 | - int ret; | |
325 | - | |
326 | - /* find ramdisk */ | |
327 | - ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, | |
328 | - &images.rd_start, &images.rd_end); | |
329 | - if (ret) { | |
330 | - puts("Ramdisk image is corrupt or invalid\n"); | |
331 | - return 1; | |
332 | - } | |
333 | - | |
334 | - return 0; | |
335 | -} | |
336 | - | |
337 | -#if defined(CONFIG_OF_LIBFDT) | |
338 | -static int bootm_find_fdt(int flag, int argc, char * const argv[]) | |
339 | -{ | |
340 | - int ret; | |
341 | - | |
342 | - /* find flattened device tree */ | |
343 | - ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, | |
344 | - &images.ft_addr, &images.ft_len); | |
345 | - if (ret) { | |
346 | - puts("Could not find a valid device tree\n"); | |
347 | - return 1; | |
348 | - } | |
349 | - | |
350 | - set_working_fdt_addr(images.ft_addr); | |
351 | - | |
352 | - return 0; | |
353 | -} | |
354 | -#endif | |
355 | - | |
356 | -static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, | |
357 | - char * const argv[]) | |
358 | -{ | |
359 | - if (((images.os.type == IH_TYPE_KERNEL) || | |
360 | - (images.os.type == IH_TYPE_KERNEL_NOLOAD) || | |
361 | - (images.os.type == IH_TYPE_MULTI)) && | |
362 | - (images.os.os == IH_OS_LINUX || | |
363 | - images.os.os == IH_OS_VXWORKS)) { | |
364 | - if (bootm_find_ramdisk(flag, argc, argv)) | |
365 | - return 1; | |
366 | - | |
367 | -#if defined(CONFIG_OF_LIBFDT) | |
368 | - if (bootm_find_fdt(flag, argc, argv)) | |
369 | - return 1; | |
370 | -#endif | |
371 | - } | |
372 | - | |
373 | - return 0; | |
374 | -} | |
375 | - | |
376 | -#define BOOTM_ERR_RESET -1 | |
377 | -#define BOOTM_ERR_OVERLAP -2 | |
378 | -#define BOOTM_ERR_UNIMPLEMENTED -3 | |
379 | -static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, | |
380 | - int boot_progress) | |
381 | -{ | |
382 | - image_info_t os = images->os; | |
383 | - uint8_t comp = os.comp; | |
384 | - ulong load = os.load; | |
385 | - ulong blob_start = os.start; | |
386 | - ulong blob_end = os.end; | |
387 | - ulong image_start = os.image_start; | |
388 | - ulong image_len = os.image_len; | |
389 | - __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN; | |
390 | - int no_overlap = 0; | |
391 | - void *load_buf, *image_buf; | |
392 | -#if defined(CONFIG_LZMA) || defined(CONFIG_LZO) | |
393 | - int ret; | |
394 | -#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */ | |
395 | - | |
396 | - const char *type_name = genimg_get_type_name(os.type); | |
397 | - | |
398 | - load_buf = map_sysmem(load, unc_len); | |
399 | - image_buf = map_sysmem(image_start, image_len); | |
400 | - switch (comp) { | |
401 | - case IH_COMP_NONE: | |
402 | - if (load == image_start) { | |
403 | - printf(" XIP %s ... ", type_name); | |
404 | - no_overlap = 1; | |
405 | - } else { | |
406 | - printf(" Loading %s ... ", type_name); | |
407 | - memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); | |
408 | - } | |
409 | - *load_end = load + image_len; | |
410 | - break; | |
411 | -#ifdef CONFIG_GZIP | |
412 | - case IH_COMP_GZIP: | |
413 | - printf(" Uncompressing %s ... ", type_name); | |
414 | - if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) { | |
415 | - puts("GUNZIP: uncompress, out-of-mem or overwrite " | |
416 | - "error - must RESET board to recover\n"); | |
417 | - if (boot_progress) | |
418 | - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
419 | - return BOOTM_ERR_RESET; | |
420 | - } | |
421 | - | |
422 | - *load_end = load + image_len; | |
423 | - break; | |
424 | -#endif /* CONFIG_GZIP */ | |
425 | -#ifdef CONFIG_BZIP2 | |
426 | - case IH_COMP_BZIP2: | |
427 | - printf(" Uncompressing %s ... ", type_name); | |
428 | - /* | |
429 | - * If we've got less than 4 MB of malloc() space, | |
430 | - * use slower decompression algorithm which requires | |
431 | - * at most 2300 KB of memory. | |
432 | - */ | |
433 | - int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len, | |
434 | - image_buf, image_len, | |
435 | - CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); | |
436 | - if (i != BZ_OK) { | |
437 | - printf("BUNZIP2: uncompress or overwrite error %d " | |
438 | - "- must RESET board to recover\n", i); | |
439 | - if (boot_progress) | |
440 | - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
441 | - return BOOTM_ERR_RESET; | |
442 | - } | |
443 | - | |
444 | - *load_end = load + unc_len; | |
445 | - break; | |
446 | -#endif /* CONFIG_BZIP2 */ | |
447 | -#ifdef CONFIG_LZMA | |
448 | - case IH_COMP_LZMA: { | |
449 | - SizeT lzma_len = unc_len; | |
450 | - printf(" Uncompressing %s ... ", type_name); | |
451 | - | |
452 | - ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, | |
453 | - image_buf, image_len); | |
454 | - unc_len = lzma_len; | |
455 | - if (ret != SZ_OK) { | |
456 | - printf("LZMA: uncompress or overwrite error %d " | |
457 | - "- must RESET board to recover\n", ret); | |
458 | - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
459 | - return BOOTM_ERR_RESET; | |
460 | - } | |
461 | - *load_end = load + unc_len; | |
462 | - break; | |
463 | - } | |
464 | -#endif /* CONFIG_LZMA */ | |
465 | -#ifdef CONFIG_LZO | |
466 | - case IH_COMP_LZO: { | |
467 | - size_t size = unc_len; | |
468 | - | |
469 | - printf(" Uncompressing %s ... ", type_name); | |
470 | - | |
471 | - ret = lzop_decompress(image_buf, image_len, load_buf, &size); | |
472 | - if (ret != LZO_E_OK) { | |
473 | - printf("LZO: uncompress or overwrite error %d " | |
474 | - "- must RESET board to recover\n", ret); | |
475 | - if (boot_progress) | |
476 | - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); | |
477 | - return BOOTM_ERR_RESET; | |
478 | - } | |
479 | - | |
480 | - *load_end = load + size; | |
481 | - break; | |
482 | - } | |
483 | -#endif /* CONFIG_LZO */ | |
484 | - default: | |
485 | - printf("Unimplemented compression type %d\n", comp); | |
486 | - return BOOTM_ERR_UNIMPLEMENTED; | |
487 | - } | |
488 | - | |
489 | - flush_cache(load, (*load_end - load) * sizeof(ulong)); | |
490 | - | |
491 | - puts("OK\n"); | |
492 | - debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); | |
493 | - bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED); | |
494 | - | |
495 | - if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) { | |
496 | - debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n", | |
497 | - blob_start, blob_end); | |
498 | - debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load, | |
499 | - *load_end); | |
500 | - | |
501 | - /* Check what type of image this is. */ | |
502 | - if (images->legacy_hdr_valid) { | |
503 | - if (image_get_type(&images->legacy_hdr_os_copy) | |
504 | - == IH_TYPE_MULTI) | |
505 | - puts("WARNING: legacy format multi component image overwritten\n"); | |
506 | - return BOOTM_ERR_OVERLAP; | |
507 | - } else { | |
508 | - puts("ERROR: new format image overwritten - must RESET the board to recover\n"); | |
509 | - bootstage_error(BOOTSTAGE_ID_OVERWRITTEN); | |
510 | - return BOOTM_ERR_RESET; | |
511 | - } | |
512 | - } | |
513 | - | |
514 | - return 0; | |
515 | -} | |
516 | - | |
517 | -static int do_bootm_standalone(int flag, int argc, char * const argv[], | |
518 | - bootm_headers_t *images) | |
519 | -{ | |
520 | - char *s; | |
521 | - int (*appl)(int, char * const []); | |
522 | - | |
523 | - /* Don't start if "autostart" is set to "no" */ | |
524 | - if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { | |
525 | - setenv_hex("filesize", images->os.image_len); | |
526 | - return 0; | |
527 | - } | |
528 | - appl = (int (*)(int, char * const []))images->ep; | |
529 | - appl(argc, argv); | |
530 | - return 0; | |
531 | -} | |
532 | - | |
533 | 43 | /* we overload the cmd field with our state machine info instead of a |
534 | 44 | * function pointer */ |
535 | 45 | static cmd_tbl_t cmd_bootm_sub[] = { |
... | ... | @@ -548,210 +58,6 @@ |
548 | 58 | U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), |
549 | 59 | }; |
550 | 60 | |
551 | -static int boot_selected_os(int argc, char * const argv[], int state, | |
552 | - bootm_headers_t *images, boot_os_fn *boot_fn) | |
553 | -{ | |
554 | - arch_preboot_os(); | |
555 | - boot_fn(state, argc, argv, images); | |
556 | - | |
557 | - /* Stand-alone may return when 'autostart' is 'no' */ | |
558 | - if (images->os.type == IH_TYPE_STANDALONE || | |
559 | - state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ | |
560 | - return 0; | |
561 | - bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); | |
562 | -#ifdef DEBUG | |
563 | - puts("\n## Control returned to monitor - resetting...\n"); | |
564 | -#endif | |
565 | - return BOOTM_ERR_RESET; | |
566 | -} | |
567 | - | |
568 | -/** | |
569 | - * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot | |
570 | - * | |
571 | - * @return interrupt flag (0 if interrupts were disabled, non-zero if they were | |
572 | - * enabled) | |
573 | - */ | |
574 | -static ulong bootm_disable_interrupts(void) | |
575 | -{ | |
576 | - ulong iflag; | |
577 | - | |
578 | - /* | |
579 | - * We have reached the point of no return: we are going to | |
580 | - * overwrite all exception vector code, so we cannot easily | |
581 | - * recover from any failures any more... | |
582 | - */ | |
583 | - iflag = disable_interrupts(); | |
584 | -#ifdef CONFIG_NETCONSOLE | |
585 | - /* Stop the ethernet stack if NetConsole could have left it up */ | |
586 | - eth_halt(); | |
587 | - eth_unregister(eth_get_dev()); | |
588 | -#endif | |
589 | - | |
590 | -#if defined(CONFIG_CMD_USB) | |
591 | - /* | |
592 | - * turn off USB to prevent the host controller from writing to the | |
593 | - * SDRAM while Linux is booting. This could happen (at least for OHCI | |
594 | - * controller), because the HCCA (Host Controller Communication Area) | |
595 | - * lies within the SDRAM and the host controller writes continously to | |
596 | - * this area (as busmaster!). The HccaFrameNumber is for example | |
597 | - * updated every 1 ms within the HCCA structure in SDRAM! For more | |
598 | - * details see the OpenHCI specification. | |
599 | - */ | |
600 | - usb_stop(); | |
601 | -#endif | |
602 | - return iflag; | |
603 | -} | |
604 | - | |
605 | -/** | |
606 | - * Execute selected states of the bootm command. | |
607 | - * | |
608 | - * Note the arguments to this state must be the first argument, Any 'bootm' | |
609 | - * or sub-command arguments must have already been taken. | |
610 | - * | |
611 | - * Note that if states contains more than one flag it MUST contain | |
612 | - * BOOTM_STATE_START, since this handles and consumes the command line args. | |
613 | - * | |
614 | - * Also note that aside from boot_os_fn functions and bootm_load_os no other | |
615 | - * functions we store the return value of in 'ret' may use a negative return | |
616 | - * value, without special handling. | |
617 | - * | |
618 | - * @param cmdtp Pointer to bootm command table entry | |
619 | - * @param flag Command flags (CMD_FLAG_...) | |
620 | - * @param argc Number of subcommand arguments (0 = no arguments) | |
621 | - * @param argv Arguments | |
622 | - * @param states Mask containing states to run (BOOTM_STATE_...) | |
623 | - * @param images Image header information | |
624 | - * @param boot_progress 1 to show boot progress, 0 to not do this | |
625 | - * @return 0 if ok, something else on error. Some errors will cause this | |
626 | - * function to perform a reboot! If states contains BOOTM_STATE_OS_GO | |
627 | - * then the intent is to boot an OS, so this function will not return | |
628 | - * unless the image type is standalone. | |
629 | - */ | |
630 | -static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, | |
631 | - char * const argv[], int states, bootm_headers_t *images, | |
632 | - int boot_progress) | |
633 | -{ | |
634 | - boot_os_fn *boot_fn; | |
635 | - ulong iflag = 0; | |
636 | - int ret = 0, need_boot_fn; | |
637 | - | |
638 | - images->state |= states; | |
639 | - | |
640 | - /* | |
641 | - * Work through the states and see how far we get. We stop on | |
642 | - * any error. | |
643 | - */ | |
644 | - if (states & BOOTM_STATE_START) | |
645 | - ret = bootm_start(cmdtp, flag, argc, argv); | |
646 | - | |
647 | - if (!ret && (states & BOOTM_STATE_FINDOS)) | |
648 | - ret = bootm_find_os(cmdtp, flag, argc, argv); | |
649 | - | |
650 | - if (!ret && (states & BOOTM_STATE_FINDOTHER)) { | |
651 | - ret = bootm_find_other(cmdtp, flag, argc, argv); | |
652 | - argc = 0; /* consume the args */ | |
653 | - } | |
654 | - | |
655 | - /* Load the OS */ | |
656 | - if (!ret && (states & BOOTM_STATE_LOADOS)) { | |
657 | - ulong load_end; | |
658 | - | |
659 | - iflag = bootm_disable_interrupts(); | |
660 | - ret = bootm_load_os(images, &load_end, 0); | |
661 | - if (ret == 0) | |
662 | - lmb_reserve(&images->lmb, images->os.load, | |
663 | - (load_end - images->os.load)); | |
664 | - else if (ret && ret != BOOTM_ERR_OVERLAP) | |
665 | - goto err; | |
666 | - else if (ret == BOOTM_ERR_OVERLAP) | |
667 | - ret = 0; | |
668 | -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) | |
669 | - if (images->os.os == IH_OS_LINUX) | |
670 | - fixup_silent_linux(); | |
671 | -#endif | |
672 | - } | |
673 | - | |
674 | - /* Relocate the ramdisk */ | |
675 | -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH | |
676 | - if (!ret && (states & BOOTM_STATE_RAMDISK)) { | |
677 | - ulong rd_len = images->rd_end - images->rd_start; | |
678 | - | |
679 | - ret = boot_ramdisk_high(&images->lmb, images->rd_start, | |
680 | - rd_len, &images->initrd_start, &images->initrd_end); | |
681 | - if (!ret) { | |
682 | - setenv_hex("initrd_start", images->initrd_start); | |
683 | - setenv_hex("initrd_end", images->initrd_end); | |
684 | - } | |
685 | - } | |
686 | -#endif | |
687 | -#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) | |
688 | - if (!ret && (states & BOOTM_STATE_FDT)) { | |
689 | - boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); | |
690 | - ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, | |
691 | - &images->ft_len); | |
692 | - } | |
693 | -#endif | |
694 | - | |
695 | - /* From now on, we need the OS boot function */ | |
696 | - if (ret) | |
697 | - return ret; | |
698 | - boot_fn = boot_os[images->os.os]; | |
699 | - need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE | | |
700 | - BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP | | |
701 | - BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO); | |
702 | - if (boot_fn == NULL && need_boot_fn) { | |
703 | - if (iflag) | |
704 | - enable_interrupts(); | |
705 | - printf("ERROR: booting os '%s' (%d) is not supported\n", | |
706 | - genimg_get_os_name(images->os.os), images->os.os); | |
707 | - bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); | |
708 | - return 1; | |
709 | - } | |
710 | - | |
711 | - /* Call various other states that are not generally used */ | |
712 | - if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) | |
713 | - ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); | |
714 | - if (!ret && (states & BOOTM_STATE_OS_BD_T)) | |
715 | - ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); | |
716 | - if (!ret && (states & BOOTM_STATE_OS_PREP)) | |
717 | - ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); | |
718 | - | |
719 | -#ifdef CONFIG_TRACE | |
720 | - /* Pretend to run the OS, then run a user command */ | |
721 | - if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { | |
722 | - char *cmd_list = getenv("fakegocmd"); | |
723 | - | |
724 | - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, | |
725 | - images, boot_fn); | |
726 | - if (!ret && cmd_list) | |
727 | - ret = run_command_list(cmd_list, -1, flag); | |
728 | - } | |
729 | -#endif | |
730 | - | |
731 | - /* Check for unsupported subcommand. */ | |
732 | - if (ret) { | |
733 | - puts("subcommand not supported\n"); | |
734 | - return ret; | |
735 | - } | |
736 | - | |
737 | - /* Now run the OS! We hope this doesn't return */ | |
738 | - if (!ret && (states & BOOTM_STATE_OS_GO)) | |
739 | - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, | |
740 | - images, boot_fn); | |
741 | - | |
742 | - /* Deal with any fallout */ | |
743 | -err: | |
744 | - if (iflag) | |
745 | - enable_interrupts(); | |
746 | - | |
747 | - if (ret == BOOTM_ERR_UNIMPLEMENTED) | |
748 | - bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); | |
749 | - else if (ret == BOOTM_ERR_RESET) | |
750 | - do_reset(cmdtp, flag, argc, argv); | |
751 | - | |
752 | - return ret; | |
753 | -} | |
754 | - | |
755 | 61 | static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, |
756 | 62 | char * const argv[]) |
757 | 63 | { |
... | ... | @@ -793,11 +99,6 @@ |
793 | 99 | if (!relocated) { |
794 | 100 | int i; |
795 | 101 | |
796 | - /* relocate boot function table */ | |
797 | - for (i = 0; i < ARRAY_SIZE(boot_os); i++) | |
798 | - if (boot_os[i] != NULL) | |
799 | - boot_os[i] += gd->reloc_off; | |
800 | - | |
801 | 102 | /* relocate names of sub-command table */ |
802 | 103 | for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++) |
803 | 104 | cmd_bootm_sub[i].name += gd->reloc_off; |
... | ... | @@ -849,196 +150,6 @@ |
849 | 150 | return 0; |
850 | 151 | } |
851 | 152 | |
852 | -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
853 | -/** | |
854 | - * image_get_kernel - verify legacy format kernel image | |
855 | - * @img_addr: in RAM address of the legacy format image to be verified | |
856 | - * @verify: data CRC verification flag | |
857 | - * | |
858 | - * image_get_kernel() verifies legacy image integrity and returns pointer to | |
859 | - * legacy image header if image verification was completed successfully. | |
860 | - * | |
861 | - * returns: | |
862 | - * pointer to a legacy image header if valid image was found | |
863 | - * otherwise return NULL | |
864 | - */ | |
865 | -static image_header_t *image_get_kernel(ulong img_addr, int verify) | |
866 | -{ | |
867 | - image_header_t *hdr = (image_header_t *)img_addr; | |
868 | - | |
869 | - if (!image_check_magic(hdr)) { | |
870 | - puts("Bad Magic Number\n"); | |
871 | - bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC); | |
872 | - return NULL; | |
873 | - } | |
874 | - bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER); | |
875 | - | |
876 | - if (!image_check_hcrc(hdr)) { | |
877 | - puts("Bad Header Checksum\n"); | |
878 | - bootstage_error(BOOTSTAGE_ID_CHECK_HEADER); | |
879 | - return NULL; | |
880 | - } | |
881 | - | |
882 | - bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM); | |
883 | - image_print_contents(hdr); | |
884 | - | |
885 | - if (verify) { | |
886 | - puts(" Verifying Checksum ... "); | |
887 | - if (!image_check_dcrc(hdr)) { | |
888 | - printf("Bad Data CRC\n"); | |
889 | - bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM); | |
890 | - return NULL; | |
891 | - } | |
892 | - puts("OK\n"); | |
893 | - } | |
894 | - bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH); | |
895 | - | |
896 | - if (!image_check_target_arch(hdr)) { | |
897 | - printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); | |
898 | - bootstage_error(BOOTSTAGE_ID_CHECK_ARCH); | |
899 | - return NULL; | |
900 | - } | |
901 | - return hdr; | |
902 | -} | |
903 | -#endif | |
904 | - | |
905 | -/** | |
906 | - * boot_get_kernel - find kernel image | |
907 | - * @os_data: pointer to a ulong variable, will hold os data start address | |
908 | - * @os_len: pointer to a ulong variable, will hold os data length | |
909 | - * | |
910 | - * boot_get_kernel() tries to find a kernel image, verifies its integrity | |
911 | - * and locates kernel data. | |
912 | - * | |
913 | - * returns: | |
914 | - * pointer to image header if valid image was found, plus kernel start | |
915 | - * address and length, otherwise NULL | |
916 | - */ | |
917 | -static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, | |
918 | - char * const argv[], bootm_headers_t *images, ulong *os_data, | |
919 | - ulong *os_len) | |
920 | -{ | |
921 | -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
922 | - image_header_t *hdr; | |
923 | -#endif | |
924 | - ulong img_addr; | |
925 | - const void *buf; | |
926 | -#if defined(CONFIG_FIT) | |
927 | - const char *fit_uname_config = NULL; | |
928 | - const char *fit_uname_kernel = NULL; | |
929 | - int os_noffset; | |
930 | -#endif | |
931 | - | |
932 | - /* find out kernel image address */ | |
933 | - if (argc < 1) { | |
934 | - img_addr = load_addr; | |
935 | - debug("* kernel: default image load address = 0x%08lx\n", | |
936 | - load_addr); | |
937 | -#if defined(CONFIG_FIT) | |
938 | - } else if (fit_parse_conf(argv[0], load_addr, &img_addr, | |
939 | - &fit_uname_config)) { | |
940 | - debug("* kernel: config '%s' from image at 0x%08lx\n", | |
941 | - fit_uname_config, img_addr); | |
942 | - } else if (fit_parse_subimage(argv[0], load_addr, &img_addr, | |
943 | - &fit_uname_kernel)) { | |
944 | - debug("* kernel: subimage '%s' from image at 0x%08lx\n", | |
945 | - fit_uname_kernel, img_addr); | |
946 | -#endif | |
947 | - } else { | |
948 | - img_addr = simple_strtoul(argv[0], NULL, 16); | |
949 | - debug("* kernel: cmdline image address = 0x%08lx\n", img_addr); | |
950 | - } | |
951 | - | |
952 | - bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); | |
953 | - | |
954 | - /* copy from dataflash if needed */ | |
955 | - img_addr = genimg_get_image(img_addr); | |
956 | - | |
957 | - /* check image type, for FIT images get FIT kernel node */ | |
958 | - *os_data = *os_len = 0; | |
959 | - buf = map_sysmem(img_addr, 0); | |
960 | - switch (genimg_get_format(buf)) { | |
961 | -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) | |
962 | - case IMAGE_FORMAT_LEGACY: | |
963 | - printf("## Booting kernel from Legacy Image at %08lx ...\n", | |
964 | - img_addr); | |
965 | - hdr = image_get_kernel(img_addr, images->verify); | |
966 | - if (!hdr) | |
967 | - return NULL; | |
968 | - bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); | |
969 | - | |
970 | - /* get os_data and os_len */ | |
971 | - switch (image_get_type(hdr)) { | |
972 | - case IH_TYPE_KERNEL: | |
973 | - case IH_TYPE_KERNEL_NOLOAD: | |
974 | - *os_data = image_get_data(hdr); | |
975 | - *os_len = image_get_data_size(hdr); | |
976 | - break; | |
977 | - case IH_TYPE_MULTI: | |
978 | - image_multi_getimg(hdr, 0, os_data, os_len); | |
979 | - break; | |
980 | - case IH_TYPE_STANDALONE: | |
981 | - *os_data = image_get_data(hdr); | |
982 | - *os_len = image_get_data_size(hdr); | |
983 | - break; | |
984 | - default: | |
985 | - printf("Wrong Image Type for %s command\n", | |
986 | - cmdtp->name); | |
987 | - bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); | |
988 | - return NULL; | |
989 | - } | |
990 | - | |
991 | - /* | |
992 | - * copy image header to allow for image overwrites during | |
993 | - * kernel decompression. | |
994 | - */ | |
995 | - memmove(&images->legacy_hdr_os_copy, hdr, | |
996 | - sizeof(image_header_t)); | |
997 | - | |
998 | - /* save pointer to image header */ | |
999 | - images->legacy_hdr_os = hdr; | |
1000 | - | |
1001 | - images->legacy_hdr_valid = 1; | |
1002 | - bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); | |
1003 | - break; | |
1004 | -#endif | |
1005 | -#if defined(CONFIG_FIT) | |
1006 | - case IMAGE_FORMAT_FIT: | |
1007 | - os_noffset = fit_image_load(images, FIT_KERNEL_PROP, | |
1008 | - img_addr, | |
1009 | - &fit_uname_kernel, &fit_uname_config, | |
1010 | - IH_ARCH_DEFAULT, IH_TYPE_KERNEL, | |
1011 | - BOOTSTAGE_ID_FIT_KERNEL_START, | |
1012 | - FIT_LOAD_IGNORED, os_data, os_len); | |
1013 | - if (os_noffset < 0) | |
1014 | - return NULL; | |
1015 | - | |
1016 | - images->fit_hdr_os = map_sysmem(img_addr, 0); | |
1017 | - images->fit_uname_os = fit_uname_kernel; | |
1018 | - images->fit_uname_cfg = fit_uname_config; | |
1019 | - images->fit_noffset_os = os_noffset; | |
1020 | - break; | |
1021 | -#endif | |
1022 | -#ifdef CONFIG_ANDROID_BOOT_IMAGE | |
1023 | - case IMAGE_FORMAT_ANDROID: | |
1024 | - printf("## Booting Android Image at 0x%08lx ...\n", img_addr); | |
1025 | - if (android_image_get_kernel((void *)img_addr, images->verify, | |
1026 | - os_data, os_len)) | |
1027 | - return NULL; | |
1028 | - break; | |
1029 | -#endif | |
1030 | - default: | |
1031 | - printf("Wrong Image Format for %s command\n", cmdtp->name); | |
1032 | - bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); | |
1033 | - return NULL; | |
1034 | - } | |
1035 | - | |
1036 | - debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", | |
1037 | - *os_data, *os_len, *os_len); | |
1038 | - | |
1039 | - return buf; | |
1040 | -} | |
1041 | - | |
1042 | 153 | #ifdef CONFIG_SYS_LONGHELP |
1043 | 154 | static char bootm_help_text[] = |
1044 | 155 | "[addr [arg ...]]\n - boot application image stored in memory\n" |
... | ... | @@ -1420,441 +531,6 @@ |
1420 | 531 | ); |
1421 | 532 | #endif |
1422 | 533 | |
1423 | -/*******************************************************************/ | |
1424 | -/* helper routines */ | |
1425 | -/*******************************************************************/ | |
1426 | -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) | |
1427 | - | |
1428 | -#define CONSOLE_ARG "console=" | |
1429 | -#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1) | |
1430 | - | |
1431 | -static void fixup_silent_linux(void) | |
1432 | -{ | |
1433 | - char *buf; | |
1434 | - const char *env_val; | |
1435 | - char *cmdline = getenv("bootargs"); | |
1436 | - int want_silent; | |
1437 | - | |
1438 | - /* | |
1439 | - * Only fix cmdline when requested. The environment variable can be: | |
1440 | - * | |
1441 | - * no - we never fixup | |
1442 | - * yes - we always fixup | |
1443 | - * unset - we rely on the console silent flag | |
1444 | - */ | |
1445 | - want_silent = getenv_yesno("silent_linux"); | |
1446 | - if (want_silent == 0) | |
1447 | - return; | |
1448 | - else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT)) | |
1449 | - return; | |
1450 | - | |
1451 | - debug("before silent fix-up: %s\n", cmdline); | |
1452 | - if (cmdline && (cmdline[0] != '\0')) { | |
1453 | - char *start = strstr(cmdline, CONSOLE_ARG); | |
1454 | - | |
1455 | - /* Allocate space for maximum possible new command line */ | |
1456 | - buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1); | |
1457 | - if (!buf) { | |
1458 | - debug("%s: out of memory\n", __func__); | |
1459 | - return; | |
1460 | - } | |
1461 | - | |
1462 | - if (start) { | |
1463 | - char *end = strchr(start, ' '); | |
1464 | - int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN; | |
1465 | - | |
1466 | - strncpy(buf, cmdline, num_start_bytes); | |
1467 | - if (end) | |
1468 | - strcpy(buf + num_start_bytes, end); | |
1469 | - else | |
1470 | - buf[num_start_bytes] = '\0'; | |
1471 | - } else { | |
1472 | - sprintf(buf, "%s %s", cmdline, CONSOLE_ARG); | |
1473 | - } | |
1474 | - env_val = buf; | |
1475 | - } else { | |
1476 | - buf = NULL; | |
1477 | - env_val = CONSOLE_ARG; | |
1478 | - } | |
1479 | - | |
1480 | - setenv("bootargs", env_val); | |
1481 | - debug("after silent fix-up: %s\n", env_val); | |
1482 | - free(buf); | |
1483 | -} | |
1484 | -#endif /* CONFIG_SILENT_CONSOLE */ | |
1485 | - | |
1486 | -#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9) | |
1487 | -static void copy_args(char *dest, int argc, char * const argv[], char delim) | |
1488 | -{ | |
1489 | - int i; | |
1490 | - | |
1491 | - for (i = 0; i < argc; i++) { | |
1492 | - if (i > 0) | |
1493 | - *dest++ = delim; | |
1494 | - strcpy(dest, argv[i]); | |
1495 | - dest += strlen(argv[i]); | |
1496 | - } | |
1497 | -} | |
1498 | -#endif | |
1499 | - | |
1500 | -/*******************************************************************/ | |
1501 | -/* OS booting routines */ | |
1502 | -/*******************************************************************/ | |
1503 | - | |
1504 | -#ifdef CONFIG_BOOTM_NETBSD | |
1505 | -static int do_bootm_netbsd(int flag, int argc, char * const argv[], | |
1506 | - bootm_headers_t *images) | |
1507 | -{ | |
1508 | - void (*loader)(bd_t *, image_header_t *, char *, char *); | |
1509 | - image_header_t *os_hdr, *hdr; | |
1510 | - ulong kernel_data, kernel_len; | |
1511 | - char *consdev; | |
1512 | - char *cmdline; | |
1513 | - | |
1514 | - if (flag != BOOTM_STATE_OS_GO) | |
1515 | - return 0; | |
1516 | - | |
1517 | -#if defined(CONFIG_FIT) | |
1518 | - if (!images->legacy_hdr_valid) { | |
1519 | - fit_unsupported_reset("NetBSD"); | |
1520 | - return 1; | |
1521 | - } | |
1522 | -#endif | |
1523 | - hdr = images->legacy_hdr_os; | |
1524 | - | |
1525 | - /* | |
1526 | - * Booting a (NetBSD) kernel image | |
1527 | - * | |
1528 | - * This process is pretty similar to a standalone application: | |
1529 | - * The (first part of an multi-) image must be a stage-2 loader, | |
1530 | - * which in turn is responsible for loading & invoking the actual | |
1531 | - * kernel. The only differences are the parameters being passed: | |
1532 | - * besides the board info strucure, the loader expects a command | |
1533 | - * line, the name of the console device, and (optionally) the | |
1534 | - * address of the original image header. | |
1535 | - */ | |
1536 | - os_hdr = NULL; | |
1537 | - if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { | |
1538 | - image_multi_getimg(hdr, 1, &kernel_data, &kernel_len); | |
1539 | - if (kernel_len) | |
1540 | - os_hdr = hdr; | |
1541 | - } | |
1542 | - | |
1543 | - consdev = ""; | |
1544 | -#if defined(CONFIG_8xx_CONS_SMC1) | |
1545 | - consdev = "smc1"; | |
1546 | -#elif defined(CONFIG_8xx_CONS_SMC2) | |
1547 | - consdev = "smc2"; | |
1548 | -#elif defined(CONFIG_8xx_CONS_SCC2) | |
1549 | - consdev = "scc2"; | |
1550 | -#elif defined(CONFIG_8xx_CONS_SCC3) | |
1551 | - consdev = "scc3"; | |
1552 | -#endif | |
1553 | - | |
1554 | - if (argc > 0) { | |
1555 | - ulong len; | |
1556 | - int i; | |
1557 | - | |
1558 | - for (i = 0, len = 0; i < argc; i += 1) | |
1559 | - len += strlen(argv[i]) + 1; | |
1560 | - cmdline = malloc(len); | |
1561 | - copy_args(cmdline, argc, argv, ' '); | |
1562 | - } else if ((cmdline = getenv("bootargs")) == NULL) { | |
1563 | - cmdline = ""; | |
1564 | - } | |
1565 | - | |
1566 | - loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep; | |
1567 | - | |
1568 | - printf("## Transferring control to NetBSD stage-2 loader " | |
1569 | - "(at address %08lx) ...\n", | |
1570 | - (ulong)loader); | |
1571 | - | |
1572 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1573 | - | |
1574 | - /* | |
1575 | - * NetBSD Stage-2 Loader Parameters: | |
1576 | - * arg[0]: pointer to board info data | |
1577 | - * arg[1]: image load address | |
1578 | - * arg[2]: char pointer to the console device to use | |
1579 | - * arg[3]: char pointer to the boot arguments | |
1580 | - */ | |
1581 | - (*loader)(gd->bd, os_hdr, consdev, cmdline); | |
1582 | - | |
1583 | - return 1; | |
1584 | -} | |
1585 | -#endif /* CONFIG_BOOTM_NETBSD*/ | |
1586 | - | |
1587 | -#ifdef CONFIG_LYNXKDI | |
1588 | -static int do_bootm_lynxkdi(int flag, int argc, char * const argv[], | |
1589 | - bootm_headers_t *images) | |
1590 | -{ | |
1591 | - image_header_t *hdr = &images->legacy_hdr_os_copy; | |
1592 | - | |
1593 | - if (flag != BOOTM_STATE_OS_GO) | |
1594 | - return 0; | |
1595 | - | |
1596 | -#if defined(CONFIG_FIT) | |
1597 | - if (!images->legacy_hdr_valid) { | |
1598 | - fit_unsupported_reset("Lynx"); | |
1599 | - return 1; | |
1600 | - } | |
1601 | -#endif | |
1602 | - | |
1603 | - lynxkdi_boot((image_header_t *)hdr); | |
1604 | - | |
1605 | - return 1; | |
1606 | -} | |
1607 | -#endif /* CONFIG_LYNXKDI */ | |
1608 | - | |
1609 | -#ifdef CONFIG_BOOTM_RTEMS | |
1610 | -static int do_bootm_rtems(int flag, int argc, char * const argv[], | |
1611 | - bootm_headers_t *images) | |
1612 | -{ | |
1613 | - void (*entry_point)(bd_t *); | |
1614 | - | |
1615 | - if (flag != BOOTM_STATE_OS_GO) | |
1616 | - return 0; | |
1617 | - | |
1618 | -#if defined(CONFIG_FIT) | |
1619 | - if (!images->legacy_hdr_valid) { | |
1620 | - fit_unsupported_reset("RTEMS"); | |
1621 | - return 1; | |
1622 | - } | |
1623 | -#endif | |
1624 | - | |
1625 | - entry_point = (void (*)(bd_t *))images->ep; | |
1626 | - | |
1627 | - printf("## Transferring control to RTEMS (at address %08lx) ...\n", | |
1628 | - (ulong)entry_point); | |
1629 | - | |
1630 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1631 | - | |
1632 | - /* | |
1633 | - * RTEMS Parameters: | |
1634 | - * r3: ptr to board info data | |
1635 | - */ | |
1636 | - (*entry_point)(gd->bd); | |
1637 | - | |
1638 | - return 1; | |
1639 | -} | |
1640 | -#endif /* CONFIG_BOOTM_RTEMS */ | |
1641 | - | |
1642 | -#if defined(CONFIG_BOOTM_OSE) | |
1643 | -static int do_bootm_ose(int flag, int argc, char * const argv[], | |
1644 | - bootm_headers_t *images) | |
1645 | -{ | |
1646 | - void (*entry_point)(void); | |
1647 | - | |
1648 | - if (flag != BOOTM_STATE_OS_GO) | |
1649 | - return 0; | |
1650 | - | |
1651 | -#if defined(CONFIG_FIT) | |
1652 | - if (!images->legacy_hdr_valid) { | |
1653 | - fit_unsupported_reset("OSE"); | |
1654 | - return 1; | |
1655 | - } | |
1656 | -#endif | |
1657 | - | |
1658 | - entry_point = (void (*)(void))images->ep; | |
1659 | - | |
1660 | - printf("## Transferring control to OSE (at address %08lx) ...\n", | |
1661 | - (ulong)entry_point); | |
1662 | - | |
1663 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1664 | - | |
1665 | - /* | |
1666 | - * OSE Parameters: | |
1667 | - * None | |
1668 | - */ | |
1669 | - (*entry_point)(); | |
1670 | - | |
1671 | - return 1; | |
1672 | -} | |
1673 | -#endif /* CONFIG_BOOTM_OSE */ | |
1674 | - | |
1675 | -#if defined(CONFIG_BOOTM_PLAN9) | |
1676 | -static int do_bootm_plan9(int flag, int argc, char * const argv[], | |
1677 | - bootm_headers_t *images) | |
1678 | -{ | |
1679 | - void (*entry_point)(void); | |
1680 | - char *s; | |
1681 | - | |
1682 | - if (flag != BOOTM_STATE_OS_GO) | |
1683 | - return 0; | |
1684 | - | |
1685 | -#if defined(CONFIG_FIT) | |
1686 | - if (!images->legacy_hdr_valid) { | |
1687 | - fit_unsupported_reset("Plan 9"); | |
1688 | - return 1; | |
1689 | - } | |
1690 | -#endif | |
1691 | - | |
1692 | - /* See README.plan9 */ | |
1693 | - s = getenv("confaddr"); | |
1694 | - if (s != NULL) { | |
1695 | - char *confaddr = (char *)simple_strtoul(s, NULL, 16); | |
1696 | - | |
1697 | - if (argc > 0) { | |
1698 | - copy_args(confaddr, argc, argv, '\n'); | |
1699 | - } else { | |
1700 | - s = getenv("bootargs"); | |
1701 | - if (s != NULL) | |
1702 | - strcpy(confaddr, s); | |
1703 | - } | |
1704 | - } | |
1705 | - | |
1706 | - entry_point = (void (*)(void))images->ep; | |
1707 | - | |
1708 | - printf("## Transferring control to Plan 9 (at address %08lx) ...\n", | |
1709 | - (ulong)entry_point); | |
1710 | - | |
1711 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1712 | - | |
1713 | - /* | |
1714 | - * Plan 9 Parameters: | |
1715 | - * None | |
1716 | - */ | |
1717 | - (*entry_point)(); | |
1718 | - | |
1719 | - return 1; | |
1720 | -} | |
1721 | -#endif /* CONFIG_BOOTM_PLAN9 */ | |
1722 | - | |
1723 | -#if defined(CONFIG_BOOTM_VXWORKS) && \ | |
1724 | - (defined(CONFIG_PPC) || defined(CONFIG_ARM)) | |
1725 | - | |
1726 | -void do_bootvx_fdt(bootm_headers_t *images) | |
1727 | -{ | |
1728 | -#if defined(CONFIG_OF_LIBFDT) | |
1729 | - int ret; | |
1730 | - char *bootline; | |
1731 | - ulong of_size = images->ft_len; | |
1732 | - char **of_flat_tree = &images->ft_addr; | |
1733 | - struct lmb *lmb = &images->lmb; | |
1734 | - | |
1735 | - if (*of_flat_tree) { | |
1736 | - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); | |
1737 | - | |
1738 | - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); | |
1739 | - if (ret) | |
1740 | - return; | |
1741 | - | |
1742 | - ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); | |
1743 | - if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { | |
1744 | - bootline = getenv("bootargs"); | |
1745 | - if (bootline) { | |
1746 | - ret = fdt_find_and_setprop(*of_flat_tree, | |
1747 | - "/chosen", "bootargs", | |
1748 | - bootline, | |
1749 | - strlen(bootline) + 1, 1); | |
1750 | - if (ret < 0) { | |
1751 | - printf("## ERROR: %s : %s\n", __func__, | |
1752 | - fdt_strerror(ret)); | |
1753 | - return; | |
1754 | - } | |
1755 | - } | |
1756 | - } else { | |
1757 | - printf("## ERROR: %s : %s\n", __func__, | |
1758 | - fdt_strerror(ret)); | |
1759 | - return; | |
1760 | - } | |
1761 | - } | |
1762 | -#endif | |
1763 | - | |
1764 | - boot_prep_vxworks(images); | |
1765 | - | |
1766 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1767 | - | |
1768 | -#if defined(CONFIG_OF_LIBFDT) | |
1769 | - printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n", | |
1770 | - (ulong)images->ep, (ulong)*of_flat_tree); | |
1771 | -#else | |
1772 | - printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); | |
1773 | -#endif | |
1774 | - | |
1775 | - boot_jump_vxworks(images); | |
1776 | - | |
1777 | - puts("## vxWorks terminated\n"); | |
1778 | -} | |
1779 | - | |
1780 | -static int do_bootm_vxworks(int flag, int argc, char * const argv[], | |
1781 | - bootm_headers_t *images) | |
1782 | -{ | |
1783 | - if (flag != BOOTM_STATE_OS_GO) | |
1784 | - return 0; | |
1785 | - | |
1786 | -#if defined(CONFIG_FIT) | |
1787 | - if (!images->legacy_hdr_valid) { | |
1788 | - fit_unsupported_reset("VxWorks"); | |
1789 | - return 1; | |
1790 | - } | |
1791 | -#endif | |
1792 | - | |
1793 | - do_bootvx_fdt(images); | |
1794 | - | |
1795 | - return 1; | |
1796 | -} | |
1797 | -#endif | |
1798 | - | |
1799 | -#if defined(CONFIG_CMD_ELF) | |
1800 | -static int do_bootm_qnxelf(int flag, int argc, char * const argv[], | |
1801 | - bootm_headers_t *images) | |
1802 | -{ | |
1803 | - char *local_args[2]; | |
1804 | - char str[16]; | |
1805 | - | |
1806 | - if (flag != BOOTM_STATE_OS_GO) | |
1807 | - return 0; | |
1808 | - | |
1809 | -#if defined(CONFIG_FIT) | |
1810 | - if (!images->legacy_hdr_valid) { | |
1811 | - fit_unsupported_reset("QNX"); | |
1812 | - return 1; | |
1813 | - } | |
1814 | -#endif | |
1815 | - | |
1816 | - sprintf(str, "%lx", images->ep); /* write entry-point into string */ | |
1817 | - local_args[0] = argv[0]; | |
1818 | - local_args[1] = str; /* and provide it via the arguments */ | |
1819 | - do_bootelf(NULL, 0, 2, local_args); | |
1820 | - | |
1821 | - return 1; | |
1822 | -} | |
1823 | -#endif | |
1824 | - | |
1825 | -#ifdef CONFIG_INTEGRITY | |
1826 | -static int do_bootm_integrity(int flag, int argc, char * const argv[], | |
1827 | - bootm_headers_t *images) | |
1828 | -{ | |
1829 | - void (*entry_point)(void); | |
1830 | - | |
1831 | - if (flag != BOOTM_STATE_OS_GO) | |
1832 | - return 0; | |
1833 | - | |
1834 | -#if defined(CONFIG_FIT) | |
1835 | - if (!images->legacy_hdr_valid) { | |
1836 | - fit_unsupported_reset("INTEGRITY"); | |
1837 | - return 1; | |
1838 | - } | |
1839 | -#endif | |
1840 | - | |
1841 | - entry_point = (void (*)(void))images->ep; | |
1842 | - | |
1843 | - printf("## Transferring control to INTEGRITY (at address %08lx) ...\n", | |
1844 | - (ulong)entry_point); | |
1845 | - | |
1846 | - bootstage_mark(BOOTSTAGE_ID_RUN_OS); | |
1847 | - | |
1848 | - /* | |
1849 | - * INTEGRITY Parameters: | |
1850 | - * None | |
1851 | - */ | |
1852 | - (*entry_point)(); | |
1853 | - | |
1854 | - return 1; | |
1855 | -} | |
1856 | -#endif | |
1857 | - | |
1858 | 534 | #ifdef CONFIG_CMD_BOOTZ |
1859 | 535 | |
1860 | 536 | int __weak bootz_setup(ulong image, ulong *start, ulong *end) |
1861 | 537 | |
... | ... | @@ -1898,13 +574,8 @@ |
1898 | 574 | * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not |
1899 | 575 | * have a header that provide this informaiton. |
1900 | 576 | */ |
1901 | - if (bootm_find_ramdisk(flag, argc, argv)) | |
577 | + if (bootm_find_ramdisk_fdt(flag, argc, argv)) | |
1902 | 578 | return 1; |
1903 | - | |
1904 | -#if defined(CONFIG_OF_LIBFDT) | |
1905 | - if (bootm_find_fdt(flag, argc, argv)) | |
1906 | - return 1; | |
1907 | -#endif | |
1908 | 579 | |
1909 | 580 | return 0; |
1910 | 581 | } |
1 | +/* | |
2 | + * (C) Copyright 2000-2009 | |
3 | + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#ifndef _BOOTM_H | |
9 | +#define _BOOTM_H | |
10 | + | |
11 | +#include <command.h> | |
12 | +#include <image.h> | |
13 | + | |
14 | +#define BOOTM_ERR_RESET (-1) | |
15 | +#define BOOTM_ERR_OVERLAP (-2) | |
16 | +#define BOOTM_ERR_UNIMPLEMENTED (-3) | |
17 | + | |
18 | +/* | |
19 | + * Continue booting an OS image; caller already has: | |
20 | + * - copied image header to global variable `header' | |
21 | + * - checked header magic number, checksums (both header & image), | |
22 | + * - verified image architecture (PPC) and type (KERNEL or MULTI), | |
23 | + * - loaded (first part of) image to header load address, | |
24 | + * - disabled interrupts. | |
25 | + * | |
26 | + * @flag: Flags indicating what to do (BOOTM_STATE_...) | |
27 | + * @argc: Number of arguments. Note that the arguments are shifted down | |
28 | + * so that 0 is the first argument not processed by U-Boot, and | |
29 | + * argc is adjusted accordingly. This avoids confusion as to how | |
30 | + * many arguments are available for the OS. | |
31 | + * @images: Pointers to os/initrd/fdt | |
32 | + * @return 1 on error. On success the OS boots so this function does | |
33 | + * not return. | |
34 | + */ | |
35 | +typedef int boot_os_fn(int flag, int argc, char * const argv[], | |
36 | + bootm_headers_t *images); | |
37 | + | |
38 | +extern boot_os_fn do_bootm_linux; | |
39 | +int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); | |
40 | +void lynxkdi_boot(image_header_t *hdr); | |
41 | + | |
42 | +boot_os_fn *bootm_os_get_boot_func(int os); | |
43 | + | |
44 | +int boot_selected_os(int argc, char * const argv[], int state, | |
45 | + bootm_headers_t *images, boot_os_fn *boot_fn); | |
46 | + | |
47 | +ulong bootm_disable_interrupts(void); | |
48 | + | |
49 | +/* This is a special function used by bootz */ | |
50 | +int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]); | |
51 | + | |
52 | +int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], | |
53 | + int states, bootm_headers_t *images, int boot_progress); | |
54 | + | |
55 | +#endif |
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798
-
mentioned in commit ba0798