blob: 20c31a775329b411fda6aafaf0e38f6842764510 [file] [log] [blame]
wdenk47d1a6e2002-11-03 00:01:44 +00001/*
Stefan Roese15940c92006-03-13 11:16:36 +01002 * (C) Copyright 2000-2006
wdenk47d1a6e2002-11-03 00:01:44 +00003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
Marian Balakowiczb97a2a02008-01-08 18:14:09 +010024
wdenk47d1a6e2002-11-03 00:01:44 +000025/*
26 * Boot support
27 */
28#include <common.h>
29#include <watchdog.h>
30#include <command.h>
wdenk47d1a6e2002-11-03 00:01:44 +000031#include <image.h>
32#include <malloc.h>
33#include <zlib.h>
wdenkc29fdfc2003-08-29 20:57:53 +000034#include <bzlib.h>
wdenk7f70e852003-05-20 14:25:27 +000035#include <environment.h>
Kumar Gala4ed65522008-02-27 21:51:47 -060036#include <lmb.h>
Kumar Gala49c3a862008-10-21 17:25:45 -050037#include <linux/ctype.h>
wdenk47d1a6e2002-11-03 00:01:44 +000038#include <asm/byteorder.h>
wdenk8bde7f72003-06-27 21:31:46 +000039
Stefan Roeseebb86c42008-07-30 09:59:51 +020040#if defined(CONFIG_CMD_USB)
Markus Klotzbücher3d71c812008-07-10 14:47:09 +020041#include <usb.h>
42#endif
43
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020044#ifdef CONFIG_SYS_HUSH_PARSER
wdenk47d1a6e2002-11-03 00:01:44 +000045#include <hush.h>
46#endif
47
Kumar Gala54f9c862008-08-15 08:24:39 -050048#if defined(CONFIG_OF_LIBFDT)
49#include <fdt.h>
50#include <libfdt.h>
51#include <fdt_support.h>
52#endif
53
Luigi 'Comio' Mantellinifc9c1722008-09-08 02:46:13 +020054#ifdef CONFIG_LZMA
55#define _7ZIP_BYTE_DEFINED /* Byte already defined by zlib */
56#include <lzma/LzmaTypes.h>
57#include <lzma/LzmaDecode.h>
58#include <lzma/LzmaTools.h>
59#endif /* CONFIG_LZMA */
60
Marian Balakowicz1ee11802008-01-08 18:17:10 +010061DECLARE_GLOBAL_DATA_PTR;
62
63extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020064#ifndef CONFIG_SYS_BOOTM_LEN
65#define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */
wdenk47d1a6e2002-11-03 00:01:44 +000066#endif
67
Marian Balakowicz321359f2008-01-08 18:11:43 +010068#ifdef CONFIG_BZIP2
69extern void bz_internal_error(int);
wdenk228f29a2002-12-08 09:53:23 +000070#endif
71
Jon Loeligerbaa26db2007-07-08 17:51:39 -050072#if defined(CONFIG_CMD_IMI)
wdenk47d1a6e2002-11-03 00:01:44 +000073static int image_info (unsigned long addr);
74#endif
wdenk27b207f2003-07-24 23:38:38 +000075
Jon Loeligerbaa26db2007-07-08 17:51:39 -050076#if defined(CONFIG_CMD_IMLS)
wdenk27b207f2003-07-24 23:38:38 +000077#include <flash.h>
Marian Balakowicze6f2e902005-10-11 19:09:42 +020078extern flash_info_t flash_info[]; /* info for FLASH chips */
wdenk27b207f2003-07-24 23:38:38 +000079static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
80#endif
81
Marian Balakowicz1ee11802008-01-08 18:17:10 +010082#ifdef CONFIG_SILENT_CONSOLE
83static void fixup_silent_linux (void);
wdenk2262cfe2002-11-18 00:14:45 +000084#endif
85
Marian Balakowicz6986a382008-03-12 10:01:05 +010086static image_header_t *image_get_kernel (ulong img_addr, int verify);
87#if defined(CONFIG_FIT)
88static int fit_check_kernel (const void *fit, int os_noffset, int verify);
89#endif
90
Marian Balakowicz9a4daad2008-02-29 14:58:34 +010091static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +010092 bootm_headers_t *images, ulong *os_data, ulong *os_len);
Marian Balakowicz1ee11802008-01-08 18:17:10 +010093extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
wdenk47d1a6e2002-11-03 00:01:44 +000094
wdenk47d1a6e2002-11-03 00:01:44 +000095/*
96 * Continue booting an OS image; caller already has:
97 * - copied image header to global variable `header'
98 * - checked header magic number, checksums (both header & image),
99 * - verified image architecture (PPC) and type (KERNEL or MULTI),
100 * - loaded (first part of) image to header load address,
101 * - disabled interrupts.
102 */
Kumar Gala40d7e992008-08-15 08:24:45 -0500103typedef int boot_os_fn (int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +0100104 bootm_headers_t *images); /* pointers to os/initrd/fdt */
wdenk47d1a6e2002-11-03 00:01:44 +0000105
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100106extern boot_os_fn do_bootm_linux;
107static boot_os_fn do_bootm_netbsd;
Marian Balakowiczf13e7b22008-01-08 18:12:17 +0100108#if defined(CONFIG_LYNXKDI)
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100109static boot_os_fn do_bootm_lynxkdi;
110extern void lynxkdi_boot (image_header_t *);
wdenk8bde7f72003-06-27 21:31:46 +0000111#endif
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100112static boot_os_fn do_bootm_rtems;
Jon Loeligerbaa26db2007-07-08 17:51:39 -0500113#if defined(CONFIG_CMD_ELF)
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100114static boot_os_fn do_bootm_vxworks;
115static boot_os_fn do_bootm_qnxelf;
116int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
117int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
Jon Loeliger90253172007-07-10 11:02:44 -0500118#endif
Peter Tyserf5ed9e32008-09-08 14:56:49 -0500119#if defined(CONFIG_INTEGRITY)
120static boot_os_fn do_bootm_integrity;
121#endif
wdenk47d1a6e2002-11-03 00:01:44 +0000122
Kumar Galabe083152008-10-21 17:25:44 -0500123boot_os_fn * boot_os[] = {
124 [IH_OS_LINUX] = do_bootm_linux,
125 [IH_OS_NETBSD] = do_bootm_netbsd,
126#ifdef CONFIG_LYNXKDI
127 [IH_OS_LYNXOS] = do_bootm_lynxkdi,
128#endif
129 [IH_OS_RTEMS] = do_bootm_rtems,
130#if defined(CONFIG_CMD_ELF)
131 [IH_OS_VXWORKS] = do_bootm_vxworks,
132 [IH_OS_QNX] = do_bootm_qnxelf,
133#endif
134#ifdef CONFIG_INTEGRITY
135 [IH_OS_INTEGRITY] = do_bootm_integrity,
136#endif
137};
138
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200139ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100140static bootm_headers_t images; /* pointers to os/initrd/fdt images */
Stefan Roese15940c92006-03-13 11:16:36 +0100141
Kumar Galae822d7f2008-02-27 21:51:49 -0600142void __board_lmb_reserve(struct lmb *lmb)
143{
144 /* please define platform specific board_lmb_reserve() */
145}
146void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));
wdenk47d1a6e2002-11-03 00:01:44 +0000147
Kumar Gala76da19d2008-10-16 21:52:08 -0500148void __arch_lmb_reserve(struct lmb *lmb)
149{
150 /* please define platform specific arch_lmb_reserve() */
151}
152void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve")));
153
Kumar Galac4f94192008-08-15 08:24:37 -0500154#if defined(__ARM__)
155 #define IH_INITRD_ARCH IH_ARCH_ARM
156#elif defined(__avr32__)
157 #define IH_INITRD_ARCH IH_ARCH_AVR32
158#elif defined(__bfin__)
159 #define IH_INITRD_ARCH IH_ARCH_BLACKFIN
160#elif defined(__I386__)
161 #define IH_INITRD_ARCH IH_ARCH_I386
162#elif defined(__M68K__)
163 #define IH_INITRD_ARCH IH_ARCH_M68K
164#elif defined(__microblaze__)
165 #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE
166#elif defined(__mips__)
167 #define IH_INITRD_ARCH IH_ARCH_MIPS
168#elif defined(__nios__)
169 #define IH_INITRD_ARCH IH_ARCH_NIOS
170#elif defined(__nios2__)
171 #define IH_INITRD_ARCH IH_ARCH_NIOS2
172#elif defined(__PPC__)
173 #define IH_INITRD_ARCH IH_ARCH_PPC
174#elif defined(__sh__)
175 #define IH_INITRD_ARCH IH_ARCH_SH
176#elif defined(__sparc__)
177 #define IH_INITRD_ARCH IH_ARCH_SPARC
178#else
179# error Unknown CPU type
180#endif
wdenk47d1a6e2002-11-03 00:01:44 +0000181
Kumar Gala396f6352008-08-15 08:24:41 -0500182static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
wdenk47d1a6e2002-11-03 00:01:44 +0000183{
Becky Bruce391fd932008-06-09 20:37:18 -0500184 ulong mem_start;
185 phys_size_t mem_size;
Kumar Gala396f6352008-08-15 08:24:41 -0500186 void *os_hdr;
Kumar Galac4f94192008-08-15 08:24:37 -0500187 int ret;
wdenk47d1a6e2002-11-03 00:01:44 +0000188
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100189 memset ((void *)&images, 0, sizeof (images));
Bartlomiej Siekaedbed242008-04-18 12:39:23 +0200190 images.verify = getenv_yesno ("verify");
wdenk47d1a6e2002-11-03 00:01:44 +0000191
Kumar Galae906cfa2008-08-15 08:24:40 -0500192 lmb_init(&images.lmb);
wdenk47d1a6e2002-11-03 00:01:44 +0000193
Kumar Galad3f2fa02008-02-27 21:51:50 -0600194 mem_start = getenv_bootm_low();
195 mem_size = getenv_bootm_size();
wdenk47d1a6e2002-11-03 00:01:44 +0000196
Kumar Galae906cfa2008-08-15 08:24:40 -0500197 lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size);
wdenk47d1a6e2002-11-03 00:01:44 +0000198
Kumar Gala76da19d2008-10-16 21:52:08 -0500199 arch_lmb_reserve(&images.lmb);
Kumar Galae906cfa2008-08-15 08:24:40 -0500200 board_lmb_reserve(&images.lmb);
wdenk47d1a6e2002-11-03 00:01:44 +0000201
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100202 /* get kernel image header, start address and length */
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100203 os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
Kumar Gala396f6352008-08-15 08:24:41 -0500204 &images, &images.os.image_start, &images.os.image_len);
205 if (images.os.image_len == 0) {
Marian Balakowicz6986a382008-03-12 10:01:05 +0100206 puts ("ERROR: can't get kernel image!\n");
wdenk47d1a6e2002-11-03 00:01:44 +0000207 return 1;
208 }
wdenk47d1a6e2002-11-03 00:01:44 +0000209
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100210 /* get image parameters */
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100211 switch (genimg_get_format (os_hdr)) {
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100212 case IMAGE_FORMAT_LEGACY:
Kumar Gala396f6352008-08-15 08:24:41 -0500213 images.os.type = image_get_type (os_hdr);
214 images.os.comp = image_get_comp (os_hdr);
215 images.os.os = image_get_os (os_hdr);
Wolfgang Denkbccae902005-10-06 01:50:50 +0200216
Kumar Gala396f6352008-08-15 08:24:41 -0500217 images.os.end = image_get_image_end (os_hdr);
218 images.os.load = image_get_load (os_hdr);
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100219 break;
220#if defined(CONFIG_FIT)
221 case IMAGE_FORMAT_FIT:
Marian Balakowicz3dfe1102008-03-12 10:32:59 +0100222 if (fit_image_get_type (images.fit_hdr_os,
Kumar Gala396f6352008-08-15 08:24:41 -0500223 images.fit_noffset_os, &images.os.type)) {
Marian Balakowicz6986a382008-03-12 10:01:05 +0100224 puts ("Can't get image type!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100225 show_boot_progress (-109);
wdenk47d1a6e2002-11-03 00:01:44 +0000226 return 1;
227 }
wdenk47d1a6e2002-11-03 00:01:44 +0000228
Marian Balakowicz3dfe1102008-03-12 10:32:59 +0100229 if (fit_image_get_comp (images.fit_hdr_os,
Kumar Gala396f6352008-08-15 08:24:41 -0500230 images.fit_noffset_os, &images.os.comp)) {
Marian Balakowicz6986a382008-03-12 10:01:05 +0100231 puts ("Can't get image compression!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100232 show_boot_progress (-110);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100233 return 1;
234 }
wdenk47d1a6e2002-11-03 00:01:44 +0000235
Marian Balakowicz3dfe1102008-03-12 10:32:59 +0100236 if (fit_image_get_os (images.fit_hdr_os,
Kumar Gala396f6352008-08-15 08:24:41 -0500237 images.fit_noffset_os, &images.os.os)) {
Marian Balakowicz6986a382008-03-12 10:01:05 +0100238 puts ("Can't get image OS!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100239 show_boot_progress (-111);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100240 return 1;
241 }
wdenk47d1a6e2002-11-03 00:01:44 +0000242
Kumar Gala396f6352008-08-15 08:24:41 -0500243 images.os.end = fit_get_end (images.fit_hdr_os);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100244
Marian Balakowicz3dfe1102008-03-12 10:32:59 +0100245 if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
Kumar Gala396f6352008-08-15 08:24:41 -0500246 &images.os.load)) {
Marian Balakowicz6986a382008-03-12 10:01:05 +0100247 puts ("Can't get image load address!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100248 show_boot_progress (-112);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100249 return 1;
wdenkb13fb012003-10-30 21:49:38 +0000250 }
251 break;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100252#endif
253 default:
254 puts ("ERROR: unknown image format type!\n");
wdenk47d1a6e2002-11-03 00:01:44 +0000255 return 1;
256 }
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100257
Kumar Galac160a952008-08-15 08:24:36 -0500258 /* find kernel entry point */
259 if (images.legacy_hdr_valid) {
260 images.ep = image_get_ep (&images.legacy_hdr_os_copy);
261#if defined(CONFIG_FIT)
262 } else if (images.fit_uname_os) {
263 ret = fit_image_get_entry (images.fit_hdr_os,
264 images.fit_noffset_os, &images.ep);
265 if (ret) {
266 puts ("Can't get entry point property!\n");
267 return 1;
268 }
269#endif
270 } else {
271 puts ("Could not find kernel entry point!\n");
272 return 1;
273 }
274
Kumar Gala396f6352008-08-15 08:24:41 -0500275 if (images.os.os == IH_OS_LINUX) {
Kumar Galac4f94192008-08-15 08:24:37 -0500276 /* find ramdisk */
277 ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
278 &images.rd_start, &images.rd_end);
279 if (ret) {
Kumar Galaea86b9e2008-08-29 19:08:29 -0500280 puts ("Ramdisk image is corrupt or invalid\n");
Kumar Galac4f94192008-08-15 08:24:37 -0500281 return 1;
282 }
Kumar Gala06a09912008-08-15 08:24:38 -0500283
284#if defined(CONFIG_OF_LIBFDT)
Jean-Christophe PLAGNIOL-VILLARD1d9af0b2008-09-09 22:18:23 +0200285#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
Kumar Gala06a09912008-08-15 08:24:38 -0500286 /* find flattened device tree */
287 ret = boot_get_fdt (flag, argc, argv, &images,
288 &images.ft_addr, &images.ft_len);
289 if (ret) {
290 puts ("Could not find a valid device tree\n");
291 return 1;
292 }
Kumar Gala54f9c862008-08-15 08:24:39 -0500293
294 set_working_fdt_addr(images.ft_addr);
Kumar Gala06a09912008-08-15 08:24:38 -0500295#endif
Jean-Christophe PLAGNIOL-VILLARD1d9af0b2008-09-09 22:18:23 +0200296#endif
Kumar Galac4f94192008-08-15 08:24:37 -0500297 }
298
Kumar Gala396f6352008-08-15 08:24:41 -0500299 images.os.start = (ulong)os_hdr;
Kumar Gala49c3a862008-10-21 17:25:45 -0500300 images.state = BOOTM_STATE_START;
Kumar Gala396f6352008-08-15 08:24:41 -0500301
302 return 0;
303}
304
305#define BOOTM_ERR_RESET -1
306#define BOOTM_ERR_OVERLAP -2
307#define BOOTM_ERR_UNIMPLEMENTED -3
308static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
309{
310 uint8_t comp = os.comp;
311 ulong load = os.load;
312 ulong blob_start = os.start;
313 ulong blob_end = os.end;
314 ulong image_start = os.image_start;
315 ulong image_len = os.image_len;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200316 uint unc_len = CONFIG_SYS_BOOTM_LEN;
Kumar Gala396f6352008-08-15 08:24:41 -0500317
318 const char *type_name = genimg_get_type_name (os.type);
319
320 switch (comp) {
321 case IH_COMP_NONE:
322 if (load == blob_start) {
323 printf (" XIP %s ... ", type_name);
324 } else {
325 printf (" Loading %s ... ", type_name);
326
327 memmove_wd ((void *)load,
328 (void *)image_start, image_len, CHUNKSZ);
329 }
330 *load_end = load + image_len;
331 puts("OK\n");
332 break;
333 case IH_COMP_GZIP:
334 printf (" Uncompressing %s ... ", type_name);
335 if (gunzip ((void *)load, unc_len,
336 (uchar *)image_start, &image_len) != 0) {
337 puts ("GUNZIP: uncompress or overwrite error "
338 "- must RESET board to recover\n");
339 if (boot_progress)
340 show_boot_progress (-6);
341 return BOOTM_ERR_RESET;
342 }
343
344 *load_end = load + image_len;
345 break;
346#ifdef CONFIG_BZIP2
347 case IH_COMP_BZIP2:
348 printf (" Uncompressing %s ... ", type_name);
349 /*
350 * If we've got less than 4 MB of malloc() space,
351 * use slower decompression algorithm which requires
352 * at most 2300 KB of memory.
353 */
354 int i = BZ2_bzBuffToBuffDecompress ((char*)load,
355 &unc_len, (char *)image_start, image_len,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200356 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
Kumar Gala396f6352008-08-15 08:24:41 -0500357 if (i != BZ_OK) {
358 printf ("BUNZIP2: uncompress or overwrite error %d "
359 "- must RESET board to recover\n", i);
360 if (boot_progress)
361 show_boot_progress (-6);
362 return BOOTM_ERR_RESET;
363 }
364
365 *load_end = load + unc_len;
366 break;
367#endif /* CONFIG_BZIP2 */
Luigi 'Comio' Mantellinifc9c1722008-09-08 02:46:13 +0200368#ifdef CONFIG_LZMA
369 case IH_COMP_LZMA:
370 printf (" Uncompressing %s ... ", type_name);
371
372 int ret = lzmaBuffToBuffDecompress(
373 (unsigned char *)load, &unc_len,
Luigi 'Comio' Mantellinid977a572008-09-13 10:04:32 +0200374 (unsigned char *)image_start, image_len);
Luigi 'Comio' Mantellinifc9c1722008-09-08 02:46:13 +0200375 if (ret != LZMA_RESULT_OK) {
376 printf ("LZMA: uncompress or overwrite error %d "
377 "- must RESET board to recover\n", ret);
378 show_boot_progress (-6);
379 return BOOTM_ERR_RESET;
380 }
381 *load_end = load + unc_len;
382 break;
383#endif /* CONFIG_LZMA */
Kumar Gala396f6352008-08-15 08:24:41 -0500384 default:
385 printf ("Unimplemented compression type %d\n", comp);
386 return BOOTM_ERR_UNIMPLEMENTED;
387 }
388 puts ("OK\n");
Jean-Christophe PLAGNIOL-VILLARD54b4ab32008-09-09 22:18:24 +0200389 debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
Kumar Gala396f6352008-08-15 08:24:41 -0500390 if (boot_progress)
391 show_boot_progress (7);
392
393 if ((load < blob_end) && (*load_end > blob_start)) {
394 debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
Jean-Christophe PLAGNIOL-VILLARD54b4ab32008-09-09 22:18:24 +0200395 debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);
Kumar Gala396f6352008-08-15 08:24:41 -0500396
397 return BOOTM_ERR_OVERLAP;
398 }
399
400 return 0;
401}
402
Kumar Gala49c3a862008-10-21 17:25:45 -0500403/* we overload the cmd field with our state machine info instead of a
404 * function pointer */
405cmd_tbl_t cmd_bootm_sub[] = {
406 U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""),
407 U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""),
408#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
409 U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""),
410#endif
411#ifdef CONFIG_OF_LIBFDT
412 U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""),
413#endif
414 U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""),
415 U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""),
416 U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""),
417 U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""),
418};
419
420int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
421{
422 int ret = 0;
423 int state;
424 cmd_tbl_t *c;
425 boot_os_fn *boot_fn;
426
427 c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub));
428
429 if (c) {
430 state = (int)c->cmd;
431
432 /* treat start special since it resets the state machine */
433 if (state == BOOTM_STATE_START) {
434 argc--;
435 argv++;
436 return bootm_start(cmdtp, flag, argc, argv);
437 }
438 }
439 /* Unrecognized command */
440 else {
441 printf ("Usage:\n%s\n", cmdtp->usage);
442 return 1;
443 }
444
445 if (images.state >= state) {
446 printf ("Trying to execute a command out of order\n");
447 printf ("Usage:\n%s\n", cmdtp->usage);
448 return 1;
449 }
450
451 images.state |= state;
452 boot_fn = boot_os[images.os.os];
453
454 switch (state) {
455 ulong load_end;
456 case BOOTM_STATE_START:
457 /* should never occur */
458 break;
459 case BOOTM_STATE_LOADOS:
460 ret = bootm_load_os(images.os, &load_end, 0);
461 if (ret)
462 return ret;
463
464 lmb_reserve(&images.lmb, images.os.load,
465 (load_end - images.os.load));
466 break;
467#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
468 case BOOTM_STATE_RAMDISK:
469 {
470 ulong rd_len = images.rd_end - images.rd_start;
471 char str[17];
472
473 ret = boot_ramdisk_high(&images.lmb, images.rd_start,
474 rd_len, &images.initrd_start, &images.initrd_end);
475 if (ret)
476 return ret;
477
478 sprintf(str, "%lx", images.initrd_start);
479 setenv("initrd_start", str);
480 sprintf(str, "%lx", images.initrd_end);
481 setenv("initrd_end", str);
482 }
483 break;
484#endif
485#ifdef CONFIG_OF_LIBFDT
486 case BOOTM_STATE_FDT:
487 {
488 ulong bootmap_base = getenv_bootm_low();
489 ret = boot_relocate_fdt(&images.lmb, bootmap_base,
490 &images.ft_addr, &images.ft_len);
491 break;
492 }
493#endif
494 case BOOTM_STATE_OS_CMDLINE:
495 ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images);
496 if (ret)
497 printf ("cmdline subcommand not supported\n");
498 break;
499 case BOOTM_STATE_OS_BD_T:
500 ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images);
501 if (ret)
502 printf ("bdt subcommand not supported\n");
503 break;
504 case BOOTM_STATE_OS_PREP:
505 ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images);
506 if (ret)
507 printf ("prep subcommand not supported\n");
508 break;
509 case BOOTM_STATE_OS_GO:
510 disable_interrupts();
511 boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
512 break;
513 }
514
515 return ret;
516}
517
Kumar Gala396f6352008-08-15 08:24:41 -0500518/*******************************************************************/
519/* bootm - boot application image from image in memory */
520/*******************************************************************/
Kumar Galabe083152008-10-21 17:25:44 -0500521static int relocated = 0;
522
Kumar Gala396f6352008-08-15 08:24:41 -0500523int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
524{
Kumar Gala396f6352008-08-15 08:24:41 -0500525 ulong iflag;
526 ulong load_end = 0;
527 int ret;
Kumar Galabe083152008-10-21 17:25:44 -0500528 boot_os_fn *boot_fn;
529
530 /* relocate boot function table */
531 if (!relocated) {
532 int i;
533 for (i = 0; i < ARRAY_SIZE(boot_os); i++)
534 boot_os[i] += gd->reloc_off;
535 relocated = 1;
536 }
Kumar Gala396f6352008-08-15 08:24:41 -0500537
Kumar Gala49c3a862008-10-21 17:25:45 -0500538 /* determine if we have a sub command */
539 if (argc > 1) {
540 char *endp;
541
542 simple_strtoul(argv[1], &endp, 16);
543 /* endp pointing to NULL means that argv[1] was just a
544 * valid number, pass it along to the normal bootm processing
545 *
546 * If endp is ':' or '#' assume a FIT identifier so pass
547 * along for normal processing.
548 *
549 * Right now we assume the first arg should never be '-'
550 */
551 if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
552 return do_bootm_subcommand(cmdtp, flag, argc, argv);
553 }
554
Anatolij Gustschin8e024942008-08-29 21:04:45 +0200555 if (bootm_start(cmdtp, flag, argc, argv))
556 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +0000557
558 /*
559 * We have reached the point of no return: we are going to
560 * overwrite all exception vector code, so we cannot easily
561 * recover from any failures any more...
562 */
wdenk47d1a6e2002-11-03 00:01:44 +0000563 iflag = disable_interrupts();
564
Stefan Roeseebb86c42008-07-30 09:59:51 +0200565#if defined(CONFIG_CMD_USB)
Wolfgang Denk699f0512008-07-15 22:22:44 +0200566 /*
567 * turn off USB to prevent the host controller from writing to the
568 * SDRAM while Linux is booting. This could happen (at least for OHCI
569 * controller), because the HCCA (Host Controller Communication Area)
570 * lies within the SDRAM and the host controller writes continously to
571 * this area (as busmaster!). The HccaFrameNumber is for example
572 * updated every 1 ms within the HCCA structure in SDRAM! For more
573 * details see the OpenHCI specification.
574 */
Markus Klotzbücher3d71c812008-07-10 14:47:09 +0200575 usb_stop();
576#endif
577
wdenkc7de8292002-11-19 11:04:11 +0000578#ifdef CONFIG_AMIGAONEG3SE
579 /*
wdenk8bde7f72003-06-27 21:31:46 +0000580 * We've possible left the caches enabled during
wdenkc7de8292002-11-19 11:04:11 +0000581 * bios emulation, so turn them off again
582 */
583 icache_disable();
wdenkc7de8292002-11-19 11:04:11 +0000584 dcache_disable();
585#endif
586
Kumar Gala396f6352008-08-15 08:24:41 -0500587 ret = bootm_load_os(images.os, &load_end, 1);
wdenk47d1a6e2002-11-03 00:01:44 +0000588
Kumar Gala396f6352008-08-15 08:24:41 -0500589 if (ret < 0) {
590 if (ret == BOOTM_ERR_RESET)
wdenk47d1a6e2002-11-03 00:01:44 +0000591 do_reset (cmdtp, flag, argc, argv);
Kumar Gala396f6352008-08-15 08:24:41 -0500592 if (ret == BOOTM_ERR_OVERLAP) {
593 if (images.legacy_hdr_valid) {
594 if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
595 puts ("WARNING: legacy format multi component "
596 "image overwritten\n");
597 } else {
598 puts ("ERROR: new format image overwritten - "
599 "must RESET the board to recover\n");
600 show_boot_progress (-113);
601 do_reset (cmdtp, flag, argc, argv);
602 }
wdenk47d1a6e2002-11-03 00:01:44 +0000603 }
Kumar Gala396f6352008-08-15 08:24:41 -0500604 if (ret == BOOTM_ERR_UNIMPLEMENTED) {
605 if (iflag)
606 enable_interrupts();
607 show_boot_progress (-7);
608 return 1;
Marian Balakowiczcb1c4892008-04-11 11:07:49 +0200609 }
wdenk47d1a6e2002-11-03 00:01:44 +0000610 }
Marian Balakowicz75824382008-01-31 13:20:06 +0100611
Kumar Gala396f6352008-08-15 08:24:41 -0500612 lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));
613
Heiko Schocherfad63402007-07-13 09:54:17 +0200614 show_boot_progress (8);
wdenk47d1a6e2002-11-03 00:01:44 +0000615
wdenkf72da342003-10-10 10:05:42 +0000616#ifdef CONFIG_SILENT_CONSOLE
Kumar Galabe083152008-10-21 17:25:44 -0500617 if (images.os.os == IH_OS_LINUX)
618 fixup_silent_linux();
wdenk1f4bb372003-07-27 00:21:01 +0000619#endif
620
Kumar Galabe083152008-10-21 17:25:44 -0500621 boot_fn = boot_os[images.os.os];
622 boot_fn(0, argc, argv, &images);
wdenk47d1a6e2002-11-03 00:01:44 +0000623
Heiko Schocherfad63402007-07-13 09:54:17 +0200624 show_boot_progress (-9);
wdenk47d1a6e2002-11-03 00:01:44 +0000625#ifdef DEBUG
wdenk4b9206e2004-03-23 22:14:11 +0000626 puts ("\n## Control returned to monitor - resetting...\n");
wdenk47d1a6e2002-11-03 00:01:44 +0000627#endif
Kumar Gala40d7e992008-08-15 08:24:45 -0500628 do_reset (cmdtp, flag, argc, argv);
Marian Balakowicza44a2692008-03-12 10:14:57 +0100629
wdenk47d1a6e2002-11-03 00:01:44 +0000630 return 1;
631}
632
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100633/**
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100634 * image_get_kernel - verify legacy format kernel image
635 * @img_addr: in RAM address of the legacy format image to be verified
636 * @verify: data CRC verification flag
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100637 *
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100638 * image_get_kernel() verifies legacy image integrity and returns pointer to
639 * legacy image header if image verification was completed successfully.
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100640 *
641 * returns:
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100642 * pointer to a legacy image header if valid image was found
643 * otherwise return NULL
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100644 */
Marian Balakowicz1efd4362008-02-27 11:02:07 +0100645static image_header_t *image_get_kernel (ulong img_addr, int verify)
646{
647 image_header_t *hdr = (image_header_t *)img_addr;
648
649 if (!image_check_magic(hdr)) {
650 puts ("Bad Magic Number\n");
651 show_boot_progress (-1);
652 return NULL;
653 }
654 show_boot_progress (2);
655
656 if (!image_check_hcrc (hdr)) {
657 puts ("Bad Header Checksum\n");
658 show_boot_progress (-2);
659 return NULL;
660 }
661
662 show_boot_progress (3);
663 image_print_contents (hdr);
664
665 if (verify) {
666 puts (" Verifying Checksum ... ");
667 if (!image_check_dcrc (hdr)) {
668 printf ("Bad Data CRC\n");
669 show_boot_progress (-3);
670 return NULL;
671 }
672 puts ("OK\n");
673 }
674 show_boot_progress (4);
675
676 if (!image_check_target_arch (hdr)) {
677 printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr));
678 show_boot_progress (-4);
679 return NULL;
680 }
681 return hdr;
682}
683
684/**
Marian Balakowicz6986a382008-03-12 10:01:05 +0100685 * fit_check_kernel - verify FIT format kernel subimage
686 * @fit_hdr: pointer to the FIT image header
687 * os_noffset: kernel subimage node offset within FIT image
688 * @verify: data CRC verification flag
689 *
690 * fit_check_kernel() verifies integrity of the kernel subimage and from
691 * specified FIT image.
692 *
693 * returns:
694 * 1, on success
695 * 0, on failure
696 */
697#if defined (CONFIG_FIT)
698static int fit_check_kernel (const void *fit, int os_noffset, int verify)
699{
700 fit_image_print (fit, os_noffset, " ");
701
702 if (verify) {
703 puts (" Verifying Hash Integrity ... ");
704 if (!fit_image_check_hashes (fit, os_noffset)) {
705 puts ("Bad Data Hash\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100706 show_boot_progress (-104);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100707 return 0;
708 }
709 puts ("OK\n");
710 }
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100711 show_boot_progress (105);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100712
713 if (!fit_image_check_target_arch (fit, os_noffset)) {
714 puts ("Unsupported Architecture\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100715 show_boot_progress (-105);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100716 return 0;
717 }
718
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100719 show_boot_progress (106);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100720 if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) {
721 puts ("Not a kernel image\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100722 show_boot_progress (-106);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100723 return 0;
724 }
725
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100726 show_boot_progress (107);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100727 return 1;
728}
729#endif /* CONFIG_FIT */
730
731/**
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100732 * boot_get_kernel - find kernel image
Marian Balakowicz1efd4362008-02-27 11:02:07 +0100733 * @os_data: pointer to a ulong variable, will hold os data start address
734 * @os_len: pointer to a ulong variable, will hold os data length
735 *
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100736 * boot_get_kernel() tries to find a kernel image, verifies its integrity
Marian Balakowicz1efd4362008-02-27 11:02:07 +0100737 * and locates kernel data.
738 *
739 * returns:
740 * pointer to image header if valid image was found, plus kernel start
741 * address and length, otherwise NULL
742 */
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100743static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +0100744 bootm_headers_t *images, ulong *os_data, ulong *os_len)
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100745{
746 image_header_t *hdr;
747 ulong img_addr;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100748#if defined(CONFIG_FIT)
749 void *fit_hdr;
750 const char *fit_uname_config = NULL;
751 const char *fit_uname_kernel = NULL;
Marian Balakowicz6986a382008-03-12 10:01:05 +0100752 const void *data;
753 size_t len;
Marian Balakowiczf773bea2008-03-12 10:35:46 +0100754 int cfg_noffset;
Marian Balakowicz6986a382008-03-12 10:01:05 +0100755 int os_noffset;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100756#endif
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100757
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100758 /* find out kernel image address */
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100759 if (argc < 2) {
760 img_addr = load_addr;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100761 debug ("* kernel: default image load address = 0x%08lx\n",
762 load_addr);
763#if defined(CONFIG_FIT)
764 } else if (fit_parse_conf (argv[1], load_addr, &img_addr,
765 &fit_uname_config)) {
766 debug ("* kernel: config '%s' from image at 0x%08lx\n",
767 fit_uname_config, img_addr);
768 } else if (fit_parse_subimage (argv[1], load_addr, &img_addr,
769 &fit_uname_kernel)) {
770 debug ("* kernel: subimage '%s' from image at 0x%08lx\n",
771 fit_uname_kernel, img_addr);
772#endif
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100773 } else {
774 img_addr = simple_strtoul(argv[1], NULL, 16);
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100775 debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr);
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100776 }
777
778 show_boot_progress (1);
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100779
Marian Balakowiczfff888a12008-02-21 17:20:19 +0100780 /* copy from dataflash if needed */
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100781 img_addr = genimg_get_image (img_addr);
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100782
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100783 /* check image type, for FIT images get FIT kernel node */
Marian Balakowicz6986a382008-03-12 10:01:05 +0100784 *os_data = *os_len = 0;
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100785 switch (genimg_get_format ((void *)img_addr)) {
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100786 case IMAGE_FORMAT_LEGACY:
Marian Balakowicz6986a382008-03-12 10:01:05 +0100787 printf ("## Booting kernel from Legacy Image at %08lx ...\n",
788 img_addr);
Marian Balakowicz1efd4362008-02-27 11:02:07 +0100789 hdr = image_get_kernel (img_addr, images->verify);
790 if (!hdr)
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100791 return NULL;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100792 show_boot_progress (5);
793
Marian Balakowicz6986a382008-03-12 10:01:05 +0100794 /* get os_data and os_len */
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100795 switch (image_get_type (hdr)) {
796 case IH_TYPE_KERNEL:
797 *os_data = image_get_data (hdr);
798 *os_len = image_get_data_size (hdr);
799 break;
800 case IH_TYPE_MULTI:
801 image_multi_getimg (hdr, 0, os_data, os_len);
802 break;
803 default:
804 printf ("Wrong Image Type for %s command\n", cmdtp->name);
805 show_boot_progress (-5);
806 return NULL;
807 }
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100808
Marian Balakowiczcb1c4892008-04-11 11:07:49 +0200809 /*
810 * copy image header to allow for image overwrites during kernel
811 * decompression.
812 */
813 memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
814
815 /* save pointer to image header */
816 images->legacy_hdr_os = hdr;
817
818 images->legacy_hdr_valid = 1;
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100819 show_boot_progress (6);
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100820 break;
821#if defined(CONFIG_FIT)
822 case IMAGE_FORMAT_FIT:
823 fit_hdr = (void *)img_addr;
Marian Balakowicz6986a382008-03-12 10:01:05 +0100824 printf ("## Booting kernel from FIT Image at %08lx ...\n",
825 img_addr);
826
827 if (!fit_check_format (fit_hdr)) {
828 puts ("Bad FIT kernel image format!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100829 show_boot_progress (-100);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100830 return NULL;
831 }
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100832 show_boot_progress (100);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100833
834 if (!fit_uname_kernel) {
835 /*
836 * no kernel image node unit name, try to get config
837 * node first. If config unit node name is NULL
838 * fit_conf_get_node() will try to find default config node
839 */
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100840 show_boot_progress (101);
Marian Balakowiczf773bea2008-03-12 10:35:46 +0100841 cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
842 if (cfg_noffset < 0) {
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100843 show_boot_progress (-101);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100844 return NULL;
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100845 }
Marian Balakowiczf773bea2008-03-12 10:35:46 +0100846 /* save configuration uname provided in the first
847 * bootm argument
848 */
849 images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
850 printf (" Using '%s' configuration\n", images->fit_uname_cfg);
851 show_boot_progress (103);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100852
Marian Balakowiczf773bea2008-03-12 10:35:46 +0100853 os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100854 fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
855 } else {
856 /* get kernel component image node offset */
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100857 show_boot_progress (102);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100858 os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel);
859 }
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100860 if (os_noffset < 0) {
861 show_boot_progress (-103);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100862 return NULL;
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100863 }
Marian Balakowicz6986a382008-03-12 10:01:05 +0100864
865 printf (" Trying '%s' kernel subimage\n", fit_uname_kernel);
866
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100867 show_boot_progress (104);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100868 if (!fit_check_kernel (fit_hdr, os_noffset, images->verify))
869 return NULL;
870
871 /* get kernel image data address and length */
872 if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) {
873 puts ("Could not find kernel subimage data!\n");
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100874 show_boot_progress (-107);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100875 return NULL;
876 }
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100877 show_boot_progress (108);
Marian Balakowicz6986a382008-03-12 10:01:05 +0100878
879 *os_len = len;
880 *os_data = (ulong)data;
881 images->fit_hdr_os = fit_hdr;
882 images->fit_uname_os = fit_uname_kernel;
Marian Balakowicz3dfe1102008-03-12 10:32:59 +0100883 images->fit_noffset_os = os_noffset;
Marian Balakowicz6986a382008-03-12 10:01:05 +0100884 break;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100885#endif
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100886 default:
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100887 printf ("Wrong Image Format for %s command\n", cmdtp->name);
Marian Balakowicz1372cce2008-03-12 10:33:01 +0100888 show_boot_progress (-108);
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100889 return NULL;
890 }
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100891
Wolfgang Denk06c53be2008-07-10 13:16:09 +0200892 debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
Marian Balakowicz6986a382008-03-12 10:01:05 +0100893 *os_data, *os_len, *os_len);
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100894
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100895 return (void *)img_addr;
Marian Balakowicz5cf746c2008-01-31 13:59:09 +0100896}
897
wdenk0d498392003-07-01 21:06:45 +0000898U_BOOT_CMD(
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200899 bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100900 "bootm - boot application image from memory\n",
901 "[addr [arg ...]]\n - boot application image stored in memory\n"
902 "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
903 "\t'arg' can be the address of an initrd image\n"
Marian Balakowicz4a2ad5f2008-01-31 13:20:07 +0100904#if defined(CONFIG_OF_LIBFDT)
Matthew McClintock98a9c4d2006-06-28 10:41:37 -0500905 "\tWhen booting a Linux kernel which requires a flat device-tree\n"
Detlev Zundel5441f612007-10-19 16:47:26 +0200906 "\ta third argument is required which is the address of the\n"
Matthew McClintock98a9c4d2006-06-28 10:41:37 -0500907 "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
908 "\tuse a '-' for the second argument. If you do not pass a third\n"
909 "\ta bd_info struct will be passed instead\n"
910#endif
Marian Balakowicz6986a382008-03-12 10:01:05 +0100911#if defined(CONFIG_FIT)
912 "\t\nFor the new multi component uImage format (FIT) addresses\n"
913 "\tmust be extened to include component or configuration unit name:\n"
914 "\taddr:<subimg_uname> - direct component image specification\n"
915 "\taddr#<conf_uname> - configuration specification\n"
916 "\tUse iminfo command to get the list of existing component\n"
917 "\timages and configurations.\n"
918#endif
Kumar Gala49c3a862008-10-21 17:25:45 -0500919 "\nSub-commands to do part of the bootm sequence. The sub-commands "
920 "must be\n"
921 "issued in the order below (it's ok to not issue all sub-commands):\n"
922 "\tstart [addr [arg ...]]\n"
923 "\tloados - load OS image\n"
924#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
925 "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
926#endif
927#if defined(CONFIG_OF_LIBFDT)
928 "\tfdt - relocate flat device tree\n"
929#endif
930 "\tbdt - OS specific bd_t processing\n"
931 "\tcmdline - OS specific command line processing/setup\n"
932 "\tprep - OS specific prep before relocation or go\n"
933 "\tgo - start OS\n"
wdenk8bde7f72003-06-27 21:31:46 +0000934);
935
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100936/*******************************************************************/
937/* bootd - boot default image */
938/*******************************************************************/
Jon Loeligerbaa26db2007-07-08 17:51:39 -0500939#if defined(CONFIG_CMD_BOOTD)
wdenk47d1a6e2002-11-03 00:01:44 +0000940int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
941{
942 int rcode = 0;
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100943
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200944#ifndef CONFIG_SYS_HUSH_PARSER
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100945 if (run_command (getenv ("bootcmd"), flag) < 0)
946 rcode = 1;
wdenk47d1a6e2002-11-03 00:01:44 +0000947#else
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100948 if (parse_string_outer (getenv ("bootcmd"),
949 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
950 rcode = 1;
wdenk47d1a6e2002-11-03 00:01:44 +0000951#endif
952 return rcode;
953}
wdenk8bde7f72003-06-27 21:31:46 +0000954
wdenk0d498392003-07-01 21:06:45 +0000955U_BOOT_CMD(
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100956 boot, 1, 1, do_bootd,
957 "boot - boot default, i.e., run 'bootcmd'\n",
wdenk9d2b18a2003-06-28 23:11:04 +0000958 NULL
959);
960
961/* keep old command name "bootd" for backward compatibility */
wdenk0d498392003-07-01 21:06:45 +0000962U_BOOT_CMD(
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100963 bootd, 1, 1, do_bootd,
964 "bootd - boot default, i.e., run 'bootcmd'\n",
wdenk8bde7f72003-06-27 21:31:46 +0000965 NULL
966);
967
wdenk47d1a6e2002-11-03 00:01:44 +0000968#endif
969
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100970
971/*******************************************************************/
972/* iminfo - print header info for a requested image */
973/*******************************************************************/
Jon Loeligerbaa26db2007-07-08 17:51:39 -0500974#if defined(CONFIG_CMD_IMI)
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100975int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
wdenk47d1a6e2002-11-03 00:01:44 +0000976{
977 int arg;
978 ulong addr;
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100979 int rcode = 0;
wdenk47d1a6e2002-11-03 00:01:44 +0000980
981 if (argc < 2) {
982 return image_info (load_addr);
983 }
984
Marian Balakowicz1ee11802008-01-08 18:17:10 +0100985 for (arg = 1; arg < argc; ++arg) {
986 addr = simple_strtoul (argv[arg], NULL, 16);
987 if (image_info (addr) != 0)
988 rcode = 1;
wdenk47d1a6e2002-11-03 00:01:44 +0000989 }
990 return rcode;
991}
992
993static int image_info (ulong addr)
994{
Marian Balakowiczd5934ad2008-02-04 08:28:09 +0100995 void *hdr = (void *)addr;
wdenk47d1a6e2002-11-03 00:01:44 +0000996
997 printf ("\n## Checking Image at %08lx ...\n", addr);
998
Marian Balakowicz9a4daad2008-02-29 14:58:34 +0100999 switch (genimg_get_format (hdr)) {
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001000 case IMAGE_FORMAT_LEGACY:
1001 puts (" Legacy image found\n");
1002 if (!image_check_magic (hdr)) {
1003 puts (" Bad Magic Number\n");
1004 return 1;
1005 }
1006
1007 if (!image_check_hcrc (hdr)) {
1008 puts (" Bad Header Checksum\n");
1009 return 1;
1010 }
1011
1012 image_print_contents (hdr);
1013
1014 puts (" Verifying Checksum ... ");
1015 if (!image_check_dcrc (hdr)) {
1016 puts (" Bad Data CRC\n");
1017 return 1;
1018 }
1019 puts ("OK\n");
1020 return 0;
1021#if defined(CONFIG_FIT)
1022 case IMAGE_FORMAT_FIT:
1023 puts (" FIT image found\n");
Marian Balakowicze32fea62008-03-11 12:35:20 +01001024
1025 if (!fit_check_format (hdr)) {
1026 puts ("Bad FIT image format!\n");
1027 return 1;
1028 }
1029
1030 fit_print_contents (hdr);
Bartlomiej Siekaa4f24342008-09-09 12:58:16 +02001031
1032 if (!fit_all_image_check_hashes (hdr)) {
1033 puts ("Bad hash in FIT image!\n");
1034 return 1;
1035 }
1036
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001037 return 0;
1038#endif
1039 default:
1040 puts ("Unknown image format!\n");
1041 break;
wdenk47d1a6e2002-11-03 00:01:44 +00001042 }
1043
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001044 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +00001045}
wdenk0d498392003-07-01 21:06:45 +00001046
1047U_BOOT_CMD(
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +02001048 iminfo, CONFIG_SYS_MAXARGS, 1, do_iminfo,
wdenk8bde7f72003-06-27 21:31:46 +00001049 "iminfo - print header information for application image\n",
1050 "addr [addr ...]\n"
1051 " - print header information for application image starting at\n"
1052 " address 'addr' in memory; this includes verification of the\n"
1053 " image contents (magic number, header and payload checksums)\n"
1054);
Jon Loeliger90253172007-07-10 11:02:44 -05001055#endif
wdenk47d1a6e2002-11-03 00:01:44 +00001056
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001057
1058/*******************************************************************/
1059/* imls - list all images found in flash */
1060/*******************************************************************/
Jon Loeligerbaa26db2007-07-08 17:51:39 -05001061#if defined(CONFIG_CMD_IMLS)
wdenk27b207f2003-07-24 23:38:38 +00001062int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
1063{
1064 flash_info_t *info;
1065 int i, j;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001066 void *hdr;
wdenk27b207f2003-07-24 23:38:38 +00001067
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001068 for (i = 0, info = &flash_info[0];
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +02001069 i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001070
wdenk27b207f2003-07-24 23:38:38 +00001071 if (info->flash_id == FLASH_UNKNOWN)
1072 goto next_bank;
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001073 for (j = 0; j < info->sector_count; ++j) {
wdenk27b207f2003-07-24 23:38:38 +00001074
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001075 hdr = (void *)info->start[j];
1076 if (!hdr)
wdenk27b207f2003-07-24 23:38:38 +00001077 goto next_sector;
1078
Marian Balakowicz9a4daad2008-02-29 14:58:34 +01001079 switch (genimg_get_format (hdr)) {
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001080 case IMAGE_FORMAT_LEGACY:
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001081 if (!image_check_hcrc (hdr))
1082 goto next_sector;
1083
1084 printf ("Legacy Image at %08lX:\n", (ulong)hdr);
1085 image_print_contents (hdr);
1086
1087 puts (" Verifying Checksum ... ");
1088 if (!image_check_dcrc (hdr)) {
1089 puts ("Bad Data CRC\n");
1090 } else {
1091 puts ("OK\n");
1092 }
1093 break;
1094#if defined(CONFIG_FIT)
1095 case IMAGE_FORMAT_FIT:
Marian Balakowicze32fea62008-03-11 12:35:20 +01001096 if (!fit_check_format (hdr))
1097 goto next_sector;
1098
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001099 printf ("FIT Image at %08lX:\n", (ulong)hdr);
Marian Balakowicze32fea62008-03-11 12:35:20 +01001100 fit_print_contents (hdr);
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001101 break;
1102#endif
1103 default:
wdenk27b207f2003-07-24 23:38:38 +00001104 goto next_sector;
wdenk5bb226e2003-11-17 21:14:37 +00001105 }
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001106
wdenkbdccc4f2003-08-05 17:43:17 +00001107next_sector: ;
wdenk27b207f2003-07-24 23:38:38 +00001108 }
wdenkbdccc4f2003-08-05 17:43:17 +00001109next_bank: ;
wdenk27b207f2003-07-24 23:38:38 +00001110 }
1111
1112 return (0);
1113}
1114
1115U_BOOT_CMD(
1116 imls, 1, 1, do_imls,
1117 "imls - list all images found in flash\n",
1118 "\n"
1119 " - Prints information about all images found at sector\n"
1120 " boundaries in flash.\n"
1121);
Jon Loeliger90253172007-07-10 11:02:44 -05001122#endif
wdenk27b207f2003-07-24 23:38:38 +00001123
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001124/*******************************************************************/
Marian Balakowicz5cf746c2008-01-31 13:59:09 +01001125/* helper routines */
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001126/*******************************************************************/
wdenk47d1a6e2002-11-03 00:01:44 +00001127#ifdef CONFIG_SILENT_CONSOLE
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001128static void fixup_silent_linux ()
wdenk47d1a6e2002-11-03 00:01:44 +00001129{
1130 char buf[256], *start, *end;
1131 char *cmdline = getenv ("bootargs");
1132
1133 /* Only fix cmdline when requested */
1134 if (!(gd->flags & GD_FLG_SILENT))
1135 return;
1136
1137 debug ("before silent fix-up: %s\n", cmdline);
1138 if (cmdline) {
1139 if ((start = strstr (cmdline, "console=")) != NULL) {
1140 end = strchr (start, ' ');
1141 strncpy (buf, cmdline, (start - cmdline + 8));
1142 if (end)
1143 strcpy (buf + (start - cmdline + 8), end);
1144 else
1145 buf[start - cmdline + 8] = '\0';
1146 } else {
1147 strcpy (buf, cmdline);
1148 strcat (buf, " console=");
1149 }
1150 } else {
1151 strcpy (buf, "console=");
1152 }
1153
1154 setenv ("bootargs", buf);
1155 debug ("after silent fix-up: %s\n", buf);
1156}
1157#endif /* CONFIG_SILENT_CONSOLE */
1158
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001159
1160/*******************************************************************/
1161/* OS booting routines */
1162/*******************************************************************/
1163
Kumar Gala40d7e992008-08-15 08:24:45 -05001164static int do_bootm_netbsd (int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +01001165 bootm_headers_t *images)
wdenk47d1a6e2002-11-03 00:01:44 +00001166{
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001167 void (*loader)(bd_t *, image_header_t *, char *, char *);
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001168 image_header_t *os_hdr, *hdr;
Marian Balakowiczf13e7b22008-01-08 18:12:17 +01001169 ulong kernel_data, kernel_len;
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001170 char *consdev;
1171 char *cmdline;
wdenk47d1a6e2002-11-03 00:01:44 +00001172
Kumar Gala49c3a862008-10-21 17:25:45 -05001173 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1174 return 1;
1175
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001176#if defined(CONFIG_FIT)
1177 if (!images->legacy_hdr_valid) {
1178 fit_unsupported_reset ("NetBSD");
Kumar Gala40d7e992008-08-15 08:24:45 -05001179 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +00001180 }
1181#endif
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001182 hdr = images->legacy_hdr_os;
wdenk47d1a6e2002-11-03 00:01:44 +00001183
1184 /*
1185 * Booting a (NetBSD) kernel image
1186 *
1187 * This process is pretty similar to a standalone application:
1188 * The (first part of an multi-) image must be a stage-2 loader,
1189 * which in turn is responsible for loading & invoking the actual
1190 * kernel. The only differences are the parameters being passed:
1191 * besides the board info strucure, the loader expects a command
1192 * line, the name of the console device, and (optionally) the
1193 * address of the original image header.
1194 */
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001195 os_hdr = NULL;
Marian Balakowiczcb1c4892008-04-11 11:07:49 +02001196 if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
Marian Balakowiczf13e7b22008-01-08 18:12:17 +01001197 image_multi_getimg (hdr, 1, &kernel_data, &kernel_len);
1198 if (kernel_len)
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001199 os_hdr = hdr;
Marian Balakowiczf13e7b22008-01-08 18:12:17 +01001200 }
wdenk47d1a6e2002-11-03 00:01:44 +00001201
1202 consdev = "";
1203#if defined (CONFIG_8xx_CONS_SMC1)
1204 consdev = "smc1";
1205#elif defined (CONFIG_8xx_CONS_SMC2)
1206 consdev = "smc2";
1207#elif defined (CONFIG_8xx_CONS_SCC2)
1208 consdev = "scc2";
1209#elif defined (CONFIG_8xx_CONS_SCC3)
1210 consdev = "scc3";
1211#endif
1212
1213 if (argc > 2) {
1214 ulong len;
1215 int i;
1216
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001217 for (i = 2, len = 0; i < argc; i += 1)
wdenk47d1a6e2002-11-03 00:01:44 +00001218 len += strlen (argv[i]) + 1;
1219 cmdline = malloc (len);
1220
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001221 for (i = 2, len = 0; i < argc; i += 1) {
wdenk47d1a6e2002-11-03 00:01:44 +00001222 if (i > 2)
1223 cmdline[len++] = ' ';
1224 strcpy (&cmdline[len], argv[i]);
1225 len += strlen (argv[i]);
1226 }
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001227 } else if ((cmdline = getenv ("bootargs")) == NULL) {
wdenk47d1a6e2002-11-03 00:01:44 +00001228 cmdline = "";
1229 }
1230
Kumar Galac160a952008-08-15 08:24:36 -05001231 loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
wdenk47d1a6e2002-11-03 00:01:44 +00001232
1233 printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
1234 (ulong)loader);
1235
1236 show_boot_progress (15);
1237
1238 /*
1239 * NetBSD Stage-2 Loader Parameters:
1240 * r3: ptr to board info data
1241 * r4: image address
1242 * r5: console device
1243 * r6: boot args string
1244 */
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001245 (*loader) (gd->bd, os_hdr, consdev, cmdline);
Kumar Gala40d7e992008-08-15 08:24:45 -05001246
1247 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +00001248}
1249
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001250#ifdef CONFIG_LYNXKDI
Kumar Gala40d7e992008-08-15 08:24:45 -05001251static int do_bootm_lynxkdi (int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +01001252 bootm_headers_t *images)
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001253{
Marian Balakowiczcb1c4892008-04-11 11:07:49 +02001254 image_header_t *hdr = &images->legacy_hdr_os_copy;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001255
Kumar Gala49c3a862008-10-21 17:25:45 -05001256 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1257 return 1;
1258
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001259#if defined(CONFIG_FIT)
1260 if (!images->legacy_hdr_valid) {
1261 fit_unsupported_reset ("Lynx");
Kumar Gala40d7e992008-08-15 08:24:45 -05001262 return 1;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001263 }
1264#endif
1265
1266 lynxkdi_boot ((image_header_t *)hdr);
Kumar Gala40d7e992008-08-15 08:24:45 -05001267
1268 return 1;
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001269}
1270#endif /* CONFIG_LYNXKDI */
1271
Kumar Gala40d7e992008-08-15 08:24:45 -05001272static int do_bootm_rtems (int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +01001273 bootm_headers_t *images)
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001274{
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001275 void (*entry_point)(bd_t *);
wdenkd791b1d2003-04-20 14:04:18 +00001276
Kumar Gala49c3a862008-10-21 17:25:45 -05001277 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1278 return 1;
1279
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001280#if defined(CONFIG_FIT)
1281 if (!images->legacy_hdr_valid) {
1282 fit_unsupported_reset ("RTEMS");
Kumar Gala40d7e992008-08-15 08:24:45 -05001283 return 1;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001284 }
1285#endif
1286
Kumar Galac160a952008-08-15 08:24:36 -05001287 entry_point = (void (*)(bd_t *))images->ep;
wdenkd791b1d2003-04-20 14:04:18 +00001288
1289 printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
1290 (ulong)entry_point);
1291
Heiko Schocherfad63402007-07-13 09:54:17 +02001292 show_boot_progress (15);
wdenkd791b1d2003-04-20 14:04:18 +00001293
1294 /*
1295 * RTEMS Parameters:
1296 * r3: ptr to board info data
1297 */
Marian Balakowicz1ee11802008-01-08 18:17:10 +01001298 (*entry_point)(gd->bd);
Kumar Gala40d7e992008-08-15 08:24:45 -05001299
1300 return 1;
wdenkd791b1d2003-04-20 14:04:18 +00001301}
1302
Jon Loeligerbaa26db2007-07-08 17:51:39 -05001303#if defined(CONFIG_CMD_ELF)
Kumar Gala40d7e992008-08-15 08:24:45 -05001304static int do_bootm_vxworks (int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +01001305 bootm_headers_t *images)
wdenk47d1a6e2002-11-03 00:01:44 +00001306{
wdenk47d1a6e2002-11-03 00:01:44 +00001307 char str[80];
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001308
Kumar Gala49c3a862008-10-21 17:25:45 -05001309 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1310 return 1;
1311
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001312#if defined(CONFIG_FIT)
Marian Balakowiczcb1c4892008-04-11 11:07:49 +02001313 if (!images->legacy_hdr_valid) {
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001314 fit_unsupported_reset ("VxWorks");
Kumar Gala40d7e992008-08-15 08:24:45 -05001315 return 1;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001316 }
1317#endif
wdenk47d1a6e2002-11-03 00:01:44 +00001318
Kumar Galac160a952008-08-15 08:24:36 -05001319 sprintf(str, "%lx", images->ep); /* write entry-point into string */
wdenk47d1a6e2002-11-03 00:01:44 +00001320 setenv("loadaddr", str);
Kumar Gala40d7e992008-08-15 08:24:45 -05001321 do_bootvx(NULL, 0, 0, NULL);
1322
1323 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +00001324}
1325
Kumar Gala40d7e992008-08-15 08:24:45 -05001326static int do_bootm_qnxelf(int flag, int argc, char *argv[],
Marian Balakowicz8a5ea3e2008-02-27 11:01:04 +01001327 bootm_headers_t *images)
wdenk47d1a6e2002-11-03 00:01:44 +00001328{
wdenk47d1a6e2002-11-03 00:01:44 +00001329 char *local_args[2];
1330 char str[16];
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001331
Kumar Gala49c3a862008-10-21 17:25:45 -05001332 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1333 return 1;
1334
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001335#if defined(CONFIG_FIT)
1336 if (!images->legacy_hdr_valid) {
1337 fit_unsupported_reset ("QNX");
Kumar Gala40d7e992008-08-15 08:24:45 -05001338 return 1;
Marian Balakowiczd5934ad2008-02-04 08:28:09 +01001339 }
1340#endif
wdenk47d1a6e2002-11-03 00:01:44 +00001341
Kumar Galac160a952008-08-15 08:24:36 -05001342 sprintf(str, "%lx", images->ep); /* write entry-point into string */
wdenk47d1a6e2002-11-03 00:01:44 +00001343 local_args[0] = argv[0];
1344 local_args[1] = str; /* and provide it via the arguments */
Kumar Gala40d7e992008-08-15 08:24:45 -05001345 do_bootelf(NULL, 0, 2, local_args);
1346
1347 return 1;
wdenk47d1a6e2002-11-03 00:01:44 +00001348}
Jon Loeliger90253172007-07-10 11:02:44 -05001349#endif
Peter Tyserf5ed9e32008-09-08 14:56:49 -05001350
1351#ifdef CONFIG_INTEGRITY
1352static int do_bootm_integrity (int flag, int argc, char *argv[],
1353 bootm_headers_t *images)
1354{
1355 void (*entry_point)(void);
1356
Kumar Gala49c3a862008-10-21 17:25:45 -05001357 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
1358 return 1;
1359
Peter Tyserf5ed9e32008-09-08 14:56:49 -05001360#if defined(CONFIG_FIT)
1361 if (!images->legacy_hdr_valid) {
1362 fit_unsupported_reset ("INTEGRITY");
1363 return 1;
1364 }
1365#endif
1366
1367 entry_point = (void (*)(void))images->ep;
1368
1369 printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n",
1370 (ulong)entry_point);
1371
1372 show_boot_progress (15);
1373
1374 /*
1375 * INTEGRITY Parameters:
1376 * None
1377 */
1378 (*entry_point)();
1379
1380 return 1;
1381}
1382#endif