cmd_bootm.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. /*
  2. * (C) Copyright 2000-2006
  3. * 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. /*
  24. * Boot support
  25. */
  26. #include <common.h>
  27. #include <watchdog.h>
  28. #include <command.h>
  29. #include <image.h>
  30. #include <malloc.h>
  31. #include <zlib.h>
  32. #include <bzlib.h>
  33. #include <environment.h>
  34. #include <lmb.h>
  35. #include <asm/byteorder.h>
  36. #if defined(CONFIG_CMD_USB)
  37. #include <usb.h>
  38. #endif
  39. #ifdef CFG_HUSH_PARSER
  40. #include <hush.h>
  41. #endif
  42. #if defined(CONFIG_OF_LIBFDT)
  43. #include <fdt.h>
  44. #include <libfdt.h>
  45. #include <fdt_support.h>
  46. #endif
  47. DECLARE_GLOBAL_DATA_PTR;
  48. extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp);
  49. #ifndef CFG_BOOTM_LEN
  50. #define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */
  51. #endif
  52. #ifdef CONFIG_BZIP2
  53. extern void bz_internal_error(int);
  54. #endif
  55. #if defined(CONFIG_CMD_IMI)
  56. static int image_info (unsigned long addr);
  57. #endif
  58. #if defined(CONFIG_CMD_IMLS)
  59. #include <flash.h>
  60. extern flash_info_t flash_info[]; /* info for FLASH chips */
  61. static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  62. #endif
  63. #ifdef CONFIG_SILENT_CONSOLE
  64. static void fixup_silent_linux (void);
  65. #endif
  66. static image_header_t *image_get_kernel (ulong img_addr, int verify);
  67. #if defined(CONFIG_FIT)
  68. static int fit_check_kernel (const void *fit, int os_noffset, int verify);
  69. #endif
  70. static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[],
  71. bootm_headers_t *images, ulong *os_data, ulong *os_len);
  72. extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  73. /*
  74. * Continue booting an OS image; caller already has:
  75. * - copied image header to global variable `header'
  76. * - checked header magic number, checksums (both header & image),
  77. * - verified image architecture (PPC) and type (KERNEL or MULTI),
  78. * - loaded (first part of) image to header load address,
  79. * - disabled interrupts.
  80. */
  81. typedef int boot_os_fn (int flag, int argc, char *argv[],
  82. bootm_headers_t *images); /* pointers to os/initrd/fdt */
  83. extern boot_os_fn do_bootm_linux;
  84. static boot_os_fn do_bootm_netbsd;
  85. #if defined(CONFIG_LYNXKDI)
  86. static boot_os_fn do_bootm_lynxkdi;
  87. extern void lynxkdi_boot (image_header_t *);
  88. #endif
  89. static boot_os_fn do_bootm_rtems;
  90. #if defined(CONFIG_CMD_ELF)
  91. static boot_os_fn do_bootm_vxworks;
  92. static boot_os_fn do_bootm_qnxelf;
  93. int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  94. int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  95. #endif
  96. ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
  97. static bootm_headers_t images; /* pointers to os/initrd/fdt images */
  98. void __board_lmb_reserve(struct lmb *lmb)
  99. {
  100. /* please define platform specific board_lmb_reserve() */
  101. }
  102. void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));
  103. #if defined(__ARM__)
  104. #define IH_INITRD_ARCH IH_ARCH_ARM
  105. #elif defined(__avr32__)
  106. #define IH_INITRD_ARCH IH_ARCH_AVR32
  107. #elif defined(__bfin__)
  108. #define IH_INITRD_ARCH IH_ARCH_BLACKFIN
  109. #elif defined(__I386__)
  110. #define IH_INITRD_ARCH IH_ARCH_I386
  111. #elif defined(__M68K__)
  112. #define IH_INITRD_ARCH IH_ARCH_M68K
  113. #elif defined(__microblaze__)
  114. #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE
  115. #elif defined(__mips__)
  116. #define IH_INITRD_ARCH IH_ARCH_MIPS
  117. #elif defined(__nios__)
  118. #define IH_INITRD_ARCH IH_ARCH_NIOS
  119. #elif defined(__nios2__)
  120. #define IH_INITRD_ARCH IH_ARCH_NIOS2
  121. #elif defined(__PPC__)
  122. #define IH_INITRD_ARCH IH_ARCH_PPC
  123. #elif defined(__sh__)
  124. #define IH_INITRD_ARCH IH_ARCH_SH
  125. #elif defined(__sparc__)
  126. #define IH_INITRD_ARCH IH_ARCH_SPARC
  127. #else
  128. # error Unknown CPU type
  129. #endif
  130. static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  131. {
  132. ulong mem_start;
  133. phys_size_t mem_size;
  134. void *os_hdr;
  135. int ret;
  136. memset ((void *)&images, 0, sizeof (images));
  137. images.verify = getenv_yesno ("verify");
  138. lmb_init(&images.lmb);
  139. mem_start = getenv_bootm_low();
  140. mem_size = getenv_bootm_size();
  141. lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size);
  142. board_lmb_reserve(&images.lmb);
  143. /* get kernel image header, start address and length */
  144. os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
  145. &images, &images.os.image_start, &images.os.image_len);
  146. if (images.os.image_len == 0) {
  147. puts ("ERROR: can't get kernel image!\n");
  148. return 1;
  149. }
  150. /* get image parameters */
  151. switch (genimg_get_format (os_hdr)) {
  152. case IMAGE_FORMAT_LEGACY:
  153. images.os.type = image_get_type (os_hdr);
  154. images.os.comp = image_get_comp (os_hdr);
  155. images.os.os = image_get_os (os_hdr);
  156. images.os.end = image_get_image_end (os_hdr);
  157. images.os.load = image_get_load (os_hdr);
  158. break;
  159. #if defined(CONFIG_FIT)
  160. case IMAGE_FORMAT_FIT:
  161. if (fit_image_get_type (images.fit_hdr_os,
  162. images.fit_noffset_os, &images.os.type)) {
  163. puts ("Can't get image type!\n");
  164. show_boot_progress (-109);
  165. return 1;
  166. }
  167. if (fit_image_get_comp (images.fit_hdr_os,
  168. images.fit_noffset_os, &images.os.comp)) {
  169. puts ("Can't get image compression!\n");
  170. show_boot_progress (-110);
  171. return 1;
  172. }
  173. if (fit_image_get_os (images.fit_hdr_os,
  174. images.fit_noffset_os, &images.os.os)) {
  175. puts ("Can't get image OS!\n");
  176. show_boot_progress (-111);
  177. return 1;
  178. }
  179. images.os.end = fit_get_end (images.fit_hdr_os);
  180. if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
  181. &images.os.load)) {
  182. puts ("Can't get image load address!\n");
  183. show_boot_progress (-112);
  184. return 1;
  185. }
  186. break;
  187. #endif
  188. default:
  189. puts ("ERROR: unknown image format type!\n");
  190. return 1;
  191. }
  192. /* find kernel entry point */
  193. if (images.legacy_hdr_valid) {
  194. images.ep = image_get_ep (&images.legacy_hdr_os_copy);
  195. #if defined(CONFIG_FIT)
  196. } else if (images.fit_uname_os) {
  197. ret = fit_image_get_entry (images.fit_hdr_os,
  198. images.fit_noffset_os, &images.ep);
  199. if (ret) {
  200. puts ("Can't get entry point property!\n");
  201. return 1;
  202. }
  203. #endif
  204. } else {
  205. puts ("Could not find kernel entry point!\n");
  206. return 1;
  207. }
  208. if (images.os.os == IH_OS_LINUX) {
  209. /* find ramdisk */
  210. ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
  211. &images.rd_start, &images.rd_end);
  212. if (ret) {
  213. puts ("Ramdisk image is corrupt or invalid\n");
  214. return 1;
  215. }
  216. #if defined(CONFIG_OF_LIBFDT)
  217. /* find flattened device tree */
  218. ret = boot_get_fdt (flag, argc, argv, &images,
  219. &images.ft_addr, &images.ft_len);
  220. if (ret) {
  221. puts ("Could not find a valid device tree\n");
  222. return 1;
  223. }
  224. set_working_fdt_addr(images.ft_addr);
  225. #endif
  226. }
  227. images.os.start = (ulong)os_hdr;
  228. images.valid = 1;
  229. return 0;
  230. }
  231. #define BOOTM_ERR_RESET -1
  232. #define BOOTM_ERR_OVERLAP -2
  233. #define BOOTM_ERR_UNIMPLEMENTED -3
  234. static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
  235. {
  236. uint8_t comp = os.comp;
  237. ulong load = os.load;
  238. ulong blob_start = os.start;
  239. ulong blob_end = os.end;
  240. ulong image_start = os.image_start;
  241. ulong image_len = os.image_len;
  242. uint unc_len = CFG_BOOTM_LEN;
  243. const char *type_name = genimg_get_type_name (os.type);
  244. switch (comp) {
  245. case IH_COMP_NONE:
  246. if (load == blob_start) {
  247. printf (" XIP %s ... ", type_name);
  248. } else {
  249. printf (" Loading %s ... ", type_name);
  250. memmove_wd ((void *)load,
  251. (void *)image_start, image_len, CHUNKSZ);
  252. }
  253. *load_end = load + image_len;
  254. puts("OK\n");
  255. break;
  256. case IH_COMP_GZIP:
  257. printf (" Uncompressing %s ... ", type_name);
  258. if (gunzip ((void *)load, unc_len,
  259. (uchar *)image_start, &image_len) != 0) {
  260. puts ("GUNZIP: uncompress or overwrite error "
  261. "- must RESET board to recover\n");
  262. if (boot_progress)
  263. show_boot_progress (-6);
  264. return BOOTM_ERR_RESET;
  265. }
  266. *load_end = load + image_len;
  267. break;
  268. #ifdef CONFIG_BZIP2
  269. case IH_COMP_BZIP2:
  270. printf (" Uncompressing %s ... ", type_name);
  271. /*
  272. * If we've got less than 4 MB of malloc() space,
  273. * use slower decompression algorithm which requires
  274. * at most 2300 KB of memory.
  275. */
  276. int i = BZ2_bzBuffToBuffDecompress ((char*)load,
  277. &unc_len, (char *)image_start, image_len,
  278. CFG_MALLOC_LEN < (4096 * 1024), 0);
  279. if (i != BZ_OK) {
  280. printf ("BUNZIP2: uncompress or overwrite error %d "
  281. "- must RESET board to recover\n", i);
  282. if (boot_progress)
  283. show_boot_progress (-6);
  284. return BOOTM_ERR_RESET;
  285. }
  286. *load_end = load + unc_len;
  287. break;
  288. #endif /* CONFIG_BZIP2 */
  289. default:
  290. printf ("Unimplemented compression type %d\n", comp);
  291. return BOOTM_ERR_UNIMPLEMENTED;
  292. }
  293. puts ("OK\n");
  294. debug (" kernel loaded at 0x%08lx, end = 0x%8p\n", load, load_end);
  295. if (boot_progress)
  296. show_boot_progress (7);
  297. if ((load < blob_end) && (*load_end > blob_start)) {
  298. debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
  299. debug ("images.os.load = 0x%lx, load_end = 0x%p\n", load, load_end);
  300. return BOOTM_ERR_OVERLAP;
  301. }
  302. return 0;
  303. }
  304. /*******************************************************************/
  305. /* bootm - boot application image from image in memory */
  306. /*******************************************************************/
  307. int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  308. {
  309. ulong iflag;
  310. ulong load_end = 0;
  311. int ret;
  312. if (bootm_start(cmdtp, flag, argc, argv))
  313. return 1;
  314. /*
  315. * We have reached the point of no return: we are going to
  316. * overwrite all exception vector code, so we cannot easily
  317. * recover from any failures any more...
  318. */
  319. iflag = disable_interrupts();
  320. #if defined(CONFIG_CMD_USB)
  321. /*
  322. * turn off USB to prevent the host controller from writing to the
  323. * SDRAM while Linux is booting. This could happen (at least for OHCI
  324. * controller), because the HCCA (Host Controller Communication Area)
  325. * lies within the SDRAM and the host controller writes continously to
  326. * this area (as busmaster!). The HccaFrameNumber is for example
  327. * updated every 1 ms within the HCCA structure in SDRAM! For more
  328. * details see the OpenHCI specification.
  329. */
  330. usb_stop();
  331. #endif
  332. #ifdef CONFIG_AMIGAONEG3SE
  333. /*
  334. * We've possible left the caches enabled during
  335. * bios emulation, so turn them off again
  336. */
  337. icache_disable();
  338. dcache_disable();
  339. #endif
  340. ret = bootm_load_os(images.os, &load_end, 1);
  341. if (ret < 0) {
  342. if (ret == BOOTM_ERR_RESET)
  343. do_reset (cmdtp, flag, argc, argv);
  344. if (ret == BOOTM_ERR_OVERLAP) {
  345. if (images.legacy_hdr_valid) {
  346. if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
  347. puts ("WARNING: legacy format multi component "
  348. "image overwritten\n");
  349. } else {
  350. puts ("ERROR: new format image overwritten - "
  351. "must RESET the board to recover\n");
  352. show_boot_progress (-113);
  353. do_reset (cmdtp, flag, argc, argv);
  354. }
  355. }
  356. if (ret == BOOTM_ERR_UNIMPLEMENTED) {
  357. if (iflag)
  358. enable_interrupts();
  359. show_boot_progress (-7);
  360. return 1;
  361. }
  362. }
  363. lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));
  364. show_boot_progress (8);
  365. switch (images.os.os) {
  366. default: /* handled by (original) Linux case */
  367. case IH_OS_LINUX:
  368. #ifdef CONFIG_SILENT_CONSOLE
  369. fixup_silent_linux();
  370. #endif
  371. do_bootm_linux (0, argc, argv, &images);
  372. break;
  373. case IH_OS_NETBSD:
  374. do_bootm_netbsd (0, argc, argv, &images);
  375. break;
  376. #ifdef CONFIG_LYNXKDI
  377. case IH_OS_LYNXOS:
  378. do_bootm_lynxkdi (0, argc, argv, &images);
  379. break;
  380. #endif
  381. case IH_OS_RTEMS:
  382. do_bootm_rtems (0, argc, argv, &images);
  383. break;
  384. #if defined(CONFIG_CMD_ELF)
  385. case IH_OS_VXWORKS:
  386. do_bootm_vxworks (0, argc, argv, &images);
  387. break;
  388. case IH_OS_QNX:
  389. do_bootm_qnxelf (0, argc, argv, &images);
  390. break;
  391. #endif
  392. }
  393. show_boot_progress (-9);
  394. #ifdef DEBUG
  395. puts ("\n## Control returned to monitor - resetting...\n");
  396. #endif
  397. do_reset (cmdtp, flag, argc, argv);
  398. return 1;
  399. }
  400. /**
  401. * image_get_kernel - verify legacy format kernel image
  402. * @img_addr: in RAM address of the legacy format image to be verified
  403. * @verify: data CRC verification flag
  404. *
  405. * image_get_kernel() verifies legacy image integrity and returns pointer to
  406. * legacy image header if image verification was completed successfully.
  407. *
  408. * returns:
  409. * pointer to a legacy image header if valid image was found
  410. * otherwise return NULL
  411. */
  412. static image_header_t *image_get_kernel (ulong img_addr, int verify)
  413. {
  414. image_header_t *hdr = (image_header_t *)img_addr;
  415. if (!image_check_magic(hdr)) {
  416. puts ("Bad Magic Number\n");
  417. show_boot_progress (-1);
  418. return NULL;
  419. }
  420. show_boot_progress (2);
  421. if (!image_check_hcrc (hdr)) {
  422. puts ("Bad Header Checksum\n");
  423. show_boot_progress (-2);
  424. return NULL;
  425. }
  426. show_boot_progress (3);
  427. image_print_contents (hdr);
  428. if (verify) {
  429. puts (" Verifying Checksum ... ");
  430. if (!image_check_dcrc (hdr)) {
  431. printf ("Bad Data CRC\n");
  432. show_boot_progress (-3);
  433. return NULL;
  434. }
  435. puts ("OK\n");
  436. }
  437. show_boot_progress (4);
  438. if (!image_check_target_arch (hdr)) {
  439. printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr));
  440. show_boot_progress (-4);
  441. return NULL;
  442. }
  443. return hdr;
  444. }
  445. /**
  446. * fit_check_kernel - verify FIT format kernel subimage
  447. * @fit_hdr: pointer to the FIT image header
  448. * os_noffset: kernel subimage node offset within FIT image
  449. * @verify: data CRC verification flag
  450. *
  451. * fit_check_kernel() verifies integrity of the kernel subimage and from
  452. * specified FIT image.
  453. *
  454. * returns:
  455. * 1, on success
  456. * 0, on failure
  457. */
  458. #if defined (CONFIG_FIT)
  459. static int fit_check_kernel (const void *fit, int os_noffset, int verify)
  460. {
  461. fit_image_print (fit, os_noffset, " ");
  462. if (verify) {
  463. puts (" Verifying Hash Integrity ... ");
  464. if (!fit_image_check_hashes (fit, os_noffset)) {
  465. puts ("Bad Data Hash\n");
  466. show_boot_progress (-104);
  467. return 0;
  468. }
  469. puts ("OK\n");
  470. }
  471. show_boot_progress (105);
  472. if (!fit_image_check_target_arch (fit, os_noffset)) {
  473. puts ("Unsupported Architecture\n");
  474. show_boot_progress (-105);
  475. return 0;
  476. }
  477. show_boot_progress (106);
  478. if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) {
  479. puts ("Not a kernel image\n");
  480. show_boot_progress (-106);
  481. return 0;
  482. }
  483. show_boot_progress (107);
  484. return 1;
  485. }
  486. #endif /* CONFIG_FIT */
  487. /**
  488. * boot_get_kernel - find kernel image
  489. * @os_data: pointer to a ulong variable, will hold os data start address
  490. * @os_len: pointer to a ulong variable, will hold os data length
  491. *
  492. * boot_get_kernel() tries to find a kernel image, verifies its integrity
  493. * and locates kernel data.
  494. *
  495. * returns:
  496. * pointer to image header if valid image was found, plus kernel start
  497. * address and length, otherwise NULL
  498. */
  499. static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
  500. bootm_headers_t *images, ulong *os_data, ulong *os_len)
  501. {
  502. image_header_t *hdr;
  503. ulong img_addr;
  504. #if defined(CONFIG_FIT)
  505. void *fit_hdr;
  506. const char *fit_uname_config = NULL;
  507. const char *fit_uname_kernel = NULL;
  508. const void *data;
  509. size_t len;
  510. int cfg_noffset;
  511. int os_noffset;
  512. #endif
  513. /* find out kernel image address */
  514. if (argc < 2) {
  515. img_addr = load_addr;
  516. debug ("* kernel: default image load address = 0x%08lx\n",
  517. load_addr);
  518. #if defined(CONFIG_FIT)
  519. } else if (fit_parse_conf (argv[1], load_addr, &img_addr,
  520. &fit_uname_config)) {
  521. debug ("* kernel: config '%s' from image at 0x%08lx\n",
  522. fit_uname_config, img_addr);
  523. } else if (fit_parse_subimage (argv[1], load_addr, &img_addr,
  524. &fit_uname_kernel)) {
  525. debug ("* kernel: subimage '%s' from image at 0x%08lx\n",
  526. fit_uname_kernel, img_addr);
  527. #endif
  528. } else {
  529. img_addr = simple_strtoul(argv[1], NULL, 16);
  530. debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr);
  531. }
  532. show_boot_progress (1);
  533. /* copy from dataflash if needed */
  534. img_addr = genimg_get_image (img_addr);
  535. /* check image type, for FIT images get FIT kernel node */
  536. *os_data = *os_len = 0;
  537. switch (genimg_get_format ((void *)img_addr)) {
  538. case IMAGE_FORMAT_LEGACY:
  539. printf ("## Booting kernel from Legacy Image at %08lx ...\n",
  540. img_addr);
  541. hdr = image_get_kernel (img_addr, images->verify);
  542. if (!hdr)
  543. return NULL;
  544. show_boot_progress (5);
  545. /* get os_data and os_len */
  546. switch (image_get_type (hdr)) {
  547. case IH_TYPE_KERNEL:
  548. *os_data = image_get_data (hdr);
  549. *os_len = image_get_data_size (hdr);
  550. break;
  551. case IH_TYPE_MULTI:
  552. image_multi_getimg (hdr, 0, os_data, os_len);
  553. break;
  554. default:
  555. printf ("Wrong Image Type for %s command\n", cmdtp->name);
  556. show_boot_progress (-5);
  557. return NULL;
  558. }
  559. /*
  560. * copy image header to allow for image overwrites during kernel
  561. * decompression.
  562. */
  563. memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
  564. /* save pointer to image header */
  565. images->legacy_hdr_os = hdr;
  566. images->legacy_hdr_valid = 1;
  567. show_boot_progress (6);
  568. break;
  569. #if defined(CONFIG_FIT)
  570. case IMAGE_FORMAT_FIT:
  571. fit_hdr = (void *)img_addr;
  572. printf ("## Booting kernel from FIT Image at %08lx ...\n",
  573. img_addr);
  574. if (!fit_check_format (fit_hdr)) {
  575. puts ("Bad FIT kernel image format!\n");
  576. show_boot_progress (-100);
  577. return NULL;
  578. }
  579. show_boot_progress (100);
  580. if (!fit_uname_kernel) {
  581. /*
  582. * no kernel image node unit name, try to get config
  583. * node first. If config unit node name is NULL
  584. * fit_conf_get_node() will try to find default config node
  585. */
  586. show_boot_progress (101);
  587. cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
  588. if (cfg_noffset < 0) {
  589. show_boot_progress (-101);
  590. return NULL;
  591. }
  592. /* save configuration uname provided in the first
  593. * bootm argument
  594. */
  595. images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
  596. printf (" Using '%s' configuration\n", images->fit_uname_cfg);
  597. show_boot_progress (103);
  598. os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
  599. fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
  600. } else {
  601. /* get kernel component image node offset */
  602. show_boot_progress (102);
  603. os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel);
  604. }
  605. if (os_noffset < 0) {
  606. show_boot_progress (-103);
  607. return NULL;
  608. }
  609. printf (" Trying '%s' kernel subimage\n", fit_uname_kernel);
  610. show_boot_progress (104);
  611. if (!fit_check_kernel (fit_hdr, os_noffset, images->verify))
  612. return NULL;
  613. /* get kernel image data address and length */
  614. if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) {
  615. puts ("Could not find kernel subimage data!\n");
  616. show_boot_progress (-107);
  617. return NULL;
  618. }
  619. show_boot_progress (108);
  620. *os_len = len;
  621. *os_data = (ulong)data;
  622. images->fit_hdr_os = fit_hdr;
  623. images->fit_uname_os = fit_uname_kernel;
  624. images->fit_noffset_os = os_noffset;
  625. break;
  626. #endif
  627. default:
  628. printf ("Wrong Image Format for %s command\n", cmdtp->name);
  629. show_boot_progress (-108);
  630. return NULL;
  631. }
  632. debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
  633. *os_data, *os_len, *os_len);
  634. return (void *)img_addr;
  635. }
  636. U_BOOT_CMD(
  637. bootm, CFG_MAXARGS, 1, do_bootm,
  638. "bootm - boot application image from memory\n",
  639. "[addr [arg ...]]\n - boot application image stored in memory\n"
  640. "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
  641. "\t'arg' can be the address of an initrd image\n"
  642. #if defined(CONFIG_OF_LIBFDT)
  643. "\tWhen booting a Linux kernel which requires a flat device-tree\n"
  644. "\ta third argument is required which is the address of the\n"
  645. "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
  646. "\tuse a '-' for the second argument. If you do not pass a third\n"
  647. "\ta bd_info struct will be passed instead\n"
  648. #endif
  649. #if defined(CONFIG_FIT)
  650. "\t\nFor the new multi component uImage format (FIT) addresses\n"
  651. "\tmust be extened to include component or configuration unit name:\n"
  652. "\taddr:<subimg_uname> - direct component image specification\n"
  653. "\taddr#<conf_uname> - configuration specification\n"
  654. "\tUse iminfo command to get the list of existing component\n"
  655. "\timages and configurations.\n"
  656. #endif
  657. );
  658. /*******************************************************************/
  659. /* bootd - boot default image */
  660. /*******************************************************************/
  661. #if defined(CONFIG_CMD_BOOTD)
  662. int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  663. {
  664. int rcode = 0;
  665. #ifndef CFG_HUSH_PARSER
  666. if (run_command (getenv ("bootcmd"), flag) < 0)
  667. rcode = 1;
  668. #else
  669. if (parse_string_outer (getenv ("bootcmd"),
  670. FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
  671. rcode = 1;
  672. #endif
  673. return rcode;
  674. }
  675. U_BOOT_CMD(
  676. boot, 1, 1, do_bootd,
  677. "boot - boot default, i.e., run 'bootcmd'\n",
  678. NULL
  679. );
  680. /* keep old command name "bootd" for backward compatibility */
  681. U_BOOT_CMD(
  682. bootd, 1, 1, do_bootd,
  683. "bootd - boot default, i.e., run 'bootcmd'\n",
  684. NULL
  685. );
  686. #endif
  687. /*******************************************************************/
  688. /* iminfo - print header info for a requested image */
  689. /*******************************************************************/
  690. #if defined(CONFIG_CMD_IMI)
  691. int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  692. {
  693. int arg;
  694. ulong addr;
  695. int rcode = 0;
  696. if (argc < 2) {
  697. return image_info (load_addr);
  698. }
  699. for (arg = 1; arg < argc; ++arg) {
  700. addr = simple_strtoul (argv[arg], NULL, 16);
  701. if (image_info (addr) != 0)
  702. rcode = 1;
  703. }
  704. return rcode;
  705. }
  706. static int image_info (ulong addr)
  707. {
  708. void *hdr = (void *)addr;
  709. printf ("\n## Checking Image at %08lx ...\n", addr);
  710. switch (genimg_get_format (hdr)) {
  711. case IMAGE_FORMAT_LEGACY:
  712. puts (" Legacy image found\n");
  713. if (!image_check_magic (hdr)) {
  714. puts (" Bad Magic Number\n");
  715. return 1;
  716. }
  717. if (!image_check_hcrc (hdr)) {
  718. puts (" Bad Header Checksum\n");
  719. return 1;
  720. }
  721. image_print_contents (hdr);
  722. puts (" Verifying Checksum ... ");
  723. if (!image_check_dcrc (hdr)) {
  724. puts (" Bad Data CRC\n");
  725. return 1;
  726. }
  727. puts ("OK\n");
  728. return 0;
  729. #if defined(CONFIG_FIT)
  730. case IMAGE_FORMAT_FIT:
  731. puts (" FIT image found\n");
  732. if (!fit_check_format (hdr)) {
  733. puts ("Bad FIT image format!\n");
  734. return 1;
  735. }
  736. fit_print_contents (hdr);
  737. return 0;
  738. #endif
  739. default:
  740. puts ("Unknown image format!\n");
  741. break;
  742. }
  743. return 1;
  744. }
  745. U_BOOT_CMD(
  746. iminfo, CFG_MAXARGS, 1, do_iminfo,
  747. "iminfo - print header information for application image\n",
  748. "addr [addr ...]\n"
  749. " - print header information for application image starting at\n"
  750. " address 'addr' in memory; this includes verification of the\n"
  751. " image contents (magic number, header and payload checksums)\n"
  752. );
  753. #endif
  754. /*******************************************************************/
  755. /* imls - list all images found in flash */
  756. /*******************************************************************/
  757. #if defined(CONFIG_CMD_IMLS)
  758. int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  759. {
  760. flash_info_t *info;
  761. int i, j;
  762. void *hdr;
  763. for (i = 0, info = &flash_info[0];
  764. i < CFG_MAX_FLASH_BANKS; ++i, ++info) {
  765. if (info->flash_id == FLASH_UNKNOWN)
  766. goto next_bank;
  767. for (j = 0; j < info->sector_count; ++j) {
  768. hdr = (void *)info->start[j];
  769. if (!hdr)
  770. goto next_sector;
  771. switch (genimg_get_format (hdr)) {
  772. case IMAGE_FORMAT_LEGACY:
  773. if (!image_check_hcrc (hdr))
  774. goto next_sector;
  775. printf ("Legacy Image at %08lX:\n", (ulong)hdr);
  776. image_print_contents (hdr);
  777. puts (" Verifying Checksum ... ");
  778. if (!image_check_dcrc (hdr)) {
  779. puts ("Bad Data CRC\n");
  780. } else {
  781. puts ("OK\n");
  782. }
  783. break;
  784. #if defined(CONFIG_FIT)
  785. case IMAGE_FORMAT_FIT:
  786. if (!fit_check_format (hdr))
  787. goto next_sector;
  788. printf ("FIT Image at %08lX:\n", (ulong)hdr);
  789. fit_print_contents (hdr);
  790. break;
  791. #endif
  792. default:
  793. goto next_sector;
  794. }
  795. next_sector: ;
  796. }
  797. next_bank: ;
  798. }
  799. return (0);
  800. }
  801. U_BOOT_CMD(
  802. imls, 1, 1, do_imls,
  803. "imls - list all images found in flash\n",
  804. "\n"
  805. " - Prints information about all images found at sector\n"
  806. " boundaries in flash.\n"
  807. );
  808. #endif
  809. /*******************************************************************/
  810. /* helper routines */
  811. /*******************************************************************/
  812. #ifdef CONFIG_SILENT_CONSOLE
  813. static void fixup_silent_linux ()
  814. {
  815. char buf[256], *start, *end;
  816. char *cmdline = getenv ("bootargs");
  817. /* Only fix cmdline when requested */
  818. if (!(gd->flags & GD_FLG_SILENT))
  819. return;
  820. debug ("before silent fix-up: %s\n", cmdline);
  821. if (cmdline) {
  822. if ((start = strstr (cmdline, "console=")) != NULL) {
  823. end = strchr (start, ' ');
  824. strncpy (buf, cmdline, (start - cmdline + 8));
  825. if (end)
  826. strcpy (buf + (start - cmdline + 8), end);
  827. else
  828. buf[start - cmdline + 8] = '\0';
  829. } else {
  830. strcpy (buf, cmdline);
  831. strcat (buf, " console=");
  832. }
  833. } else {
  834. strcpy (buf, "console=");
  835. }
  836. setenv ("bootargs", buf);
  837. debug ("after silent fix-up: %s\n", buf);
  838. }
  839. #endif /* CONFIG_SILENT_CONSOLE */
  840. /*******************************************************************/
  841. /* OS booting routines */
  842. /*******************************************************************/
  843. static int do_bootm_netbsd (int flag, int argc, char *argv[],
  844. bootm_headers_t *images)
  845. {
  846. void (*loader)(bd_t *, image_header_t *, char *, char *);
  847. image_header_t *os_hdr, *hdr;
  848. ulong kernel_data, kernel_len;
  849. char *consdev;
  850. char *cmdline;
  851. #if defined(CONFIG_FIT)
  852. if (!images->legacy_hdr_valid) {
  853. fit_unsupported_reset ("NetBSD");
  854. return 1;
  855. }
  856. #endif
  857. hdr = images->legacy_hdr_os;
  858. /*
  859. * Booting a (NetBSD) kernel image
  860. *
  861. * This process is pretty similar to a standalone application:
  862. * The (first part of an multi-) image must be a stage-2 loader,
  863. * which in turn is responsible for loading & invoking the actual
  864. * kernel. The only differences are the parameters being passed:
  865. * besides the board info strucure, the loader expects a command
  866. * line, the name of the console device, and (optionally) the
  867. * address of the original image header.
  868. */
  869. os_hdr = NULL;
  870. if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
  871. image_multi_getimg (hdr, 1, &kernel_data, &kernel_len);
  872. if (kernel_len)
  873. os_hdr = hdr;
  874. }
  875. consdev = "";
  876. #if defined (CONFIG_8xx_CONS_SMC1)
  877. consdev = "smc1";
  878. #elif defined (CONFIG_8xx_CONS_SMC2)
  879. consdev = "smc2";
  880. #elif defined (CONFIG_8xx_CONS_SCC2)
  881. consdev = "scc2";
  882. #elif defined (CONFIG_8xx_CONS_SCC3)
  883. consdev = "scc3";
  884. #endif
  885. if (argc > 2) {
  886. ulong len;
  887. int i;
  888. for (i = 2, len = 0; i < argc; i += 1)
  889. len += strlen (argv[i]) + 1;
  890. cmdline = malloc (len);
  891. for (i = 2, len = 0; i < argc; i += 1) {
  892. if (i > 2)
  893. cmdline[len++] = ' ';
  894. strcpy (&cmdline[len], argv[i]);
  895. len += strlen (argv[i]);
  896. }
  897. } else if ((cmdline = getenv ("bootargs")) == NULL) {
  898. cmdline = "";
  899. }
  900. loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
  901. printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
  902. (ulong)loader);
  903. show_boot_progress (15);
  904. /*
  905. * NetBSD Stage-2 Loader Parameters:
  906. * r3: ptr to board info data
  907. * r4: image address
  908. * r5: console device
  909. * r6: boot args string
  910. */
  911. (*loader) (gd->bd, os_hdr, consdev, cmdline);
  912. return 1;
  913. }
  914. #ifdef CONFIG_LYNXKDI
  915. static int do_bootm_lynxkdi (int flag, int argc, char *argv[],
  916. bootm_headers_t *images)
  917. {
  918. image_header_t *hdr = &images->legacy_hdr_os_copy;
  919. #if defined(CONFIG_FIT)
  920. if (!images->legacy_hdr_valid) {
  921. fit_unsupported_reset ("Lynx");
  922. return 1;
  923. }
  924. #endif
  925. lynxkdi_boot ((image_header_t *)hdr);
  926. return 1;
  927. }
  928. #endif /* CONFIG_LYNXKDI */
  929. static int do_bootm_rtems (int flag, int argc, char *argv[],
  930. bootm_headers_t *images)
  931. {
  932. void (*entry_point)(bd_t *);
  933. #if defined(CONFIG_FIT)
  934. if (!images->legacy_hdr_valid) {
  935. fit_unsupported_reset ("RTEMS");
  936. return 1;
  937. }
  938. #endif
  939. entry_point = (void (*)(bd_t *))images->ep;
  940. printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
  941. (ulong)entry_point);
  942. show_boot_progress (15);
  943. /*
  944. * RTEMS Parameters:
  945. * r3: ptr to board info data
  946. */
  947. (*entry_point)(gd->bd);
  948. return 1;
  949. }
  950. #if defined(CONFIG_CMD_ELF)
  951. static int do_bootm_vxworks (int flag, int argc, char *argv[],
  952. bootm_headers_t *images)
  953. {
  954. char str[80];
  955. #if defined(CONFIG_FIT)
  956. if (!images->legacy_hdr_valid) {
  957. fit_unsupported_reset ("VxWorks");
  958. return 1;
  959. }
  960. #endif
  961. sprintf(str, "%lx", images->ep); /* write entry-point into string */
  962. setenv("loadaddr", str);
  963. do_bootvx(NULL, 0, 0, NULL);
  964. return 1;
  965. }
  966. static int do_bootm_qnxelf(int flag, int argc, char *argv[],
  967. bootm_headers_t *images)
  968. {
  969. char *local_args[2];
  970. char str[16];
  971. #if defined(CONFIG_FIT)
  972. if (!images->legacy_hdr_valid) {
  973. fit_unsupported_reset ("QNX");
  974. return 1;
  975. }
  976. #endif
  977. sprintf(str, "%lx", images->ep); /* write entry-point into string */
  978. local_args[0] = argv[0];
  979. local_args[1] = str; /* and provide it via the arguments */
  980. do_bootelf(NULL, 0, 2, local_args);
  981. return 1;
  982. }
  983. #endif