bootm.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2009
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. */
  6. #ifndef USE_HOSTCC
  7. #include <common.h>
  8. #include <bootstage.h>
  9. #include <cli.h>
  10. #include <cpu_func.h>
  11. #include <env.h>
  12. #include <errno.h>
  13. #include <fdt_support.h>
  14. #include <irq_func.h>
  15. #include <lmb.h>
  16. #include <log.h>
  17. #include <malloc.h>
  18. #include <mapmem.h>
  19. #include <net.h>
  20. #include <asm/cache.h>
  21. #include <asm/global_data.h>
  22. #include <asm/io.h>
  23. #include <linux/sizes.h>
  24. #if defined(CONFIG_CMD_USB)
  25. #include <usb.h>
  26. #endif
  27. #else
  28. #include "mkimage.h"
  29. #endif
  30. #include <command.h>
  31. #include <bootm.h>
  32. #include <image.h>
  33. #ifndef CONFIG_SYS_BOOTM_LEN
  34. /* use 8MByte as default max gunzip size */
  35. #define CONFIG_SYS_BOOTM_LEN 0x800000
  36. #endif
  37. #define MAX_CMDLINE_SIZE SZ_4K
  38. #define IH_INITRD_ARCH IH_ARCH_DEFAULT
  39. #ifndef USE_HOSTCC
  40. DECLARE_GLOBAL_DATA_PTR;
  41. bootm_headers_t images; /* pointers to os/initrd/fdt images */
  42. static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
  43. char *const argv[], bootm_headers_t *images,
  44. ulong *os_data, ulong *os_len);
  45. __weak void board_quiesce_devices(void)
  46. {
  47. }
  48. #ifdef CONFIG_LMB
  49. static void boot_start_lmb(bootm_headers_t *images)
  50. {
  51. ulong mem_start;
  52. phys_size_t mem_size;
  53. mem_start = env_get_bootm_low();
  54. mem_size = env_get_bootm_size();
  55. lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
  56. mem_size, NULL);
  57. }
  58. #else
  59. #define lmb_reserve(lmb, base, size)
  60. static inline void boot_start_lmb(bootm_headers_t *images) { }
  61. #endif
  62. static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
  63. char *const argv[])
  64. {
  65. memset((void *)&images, 0, sizeof(images));
  66. images.verify = env_get_yesno("verify");
  67. boot_start_lmb(&images);
  68. bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
  69. images.state = BOOTM_STATE_START;
  70. return 0;
  71. }
  72. static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
  73. char *const argv[])
  74. {
  75. const void *os_hdr;
  76. bool ep_found = false;
  77. int ret;
  78. /* get kernel image header, start address and length */
  79. os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
  80. &images, &images.os.image_start, &images.os.image_len);
  81. if (images.os.image_len == 0) {
  82. puts("ERROR: can't get kernel image!\n");
  83. return 1;
  84. }
  85. /* get image parameters */
  86. switch (genimg_get_format(os_hdr)) {
  87. #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
  88. case IMAGE_FORMAT_LEGACY:
  89. images.os.type = image_get_type(os_hdr);
  90. images.os.comp = image_get_comp(os_hdr);
  91. images.os.os = image_get_os(os_hdr);
  92. images.os.end = image_get_image_end(os_hdr);
  93. images.os.load = image_get_load(os_hdr);
  94. images.os.arch = image_get_arch(os_hdr);
  95. break;
  96. #endif
  97. #if IMAGE_ENABLE_FIT
  98. case IMAGE_FORMAT_FIT:
  99. if (fit_image_get_type(images.fit_hdr_os,
  100. images.fit_noffset_os,
  101. &images.os.type)) {
  102. puts("Can't get image type!\n");
  103. bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
  104. return 1;
  105. }
  106. if (fit_image_get_comp(images.fit_hdr_os,
  107. images.fit_noffset_os,
  108. &images.os.comp)) {
  109. puts("Can't get image compression!\n");
  110. bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
  111. return 1;
  112. }
  113. if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
  114. &images.os.os)) {
  115. puts("Can't get image OS!\n");
  116. bootstage_error(BOOTSTAGE_ID_FIT_OS);
  117. return 1;
  118. }
  119. if (fit_image_get_arch(images.fit_hdr_os,
  120. images.fit_noffset_os,
  121. &images.os.arch)) {
  122. puts("Can't get image ARCH!\n");
  123. return 1;
  124. }
  125. images.os.end = fit_get_end(images.fit_hdr_os);
  126. if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
  127. &images.os.load)) {
  128. puts("Can't get image load address!\n");
  129. bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
  130. return 1;
  131. }
  132. break;
  133. #endif
  134. #ifdef CONFIG_ANDROID_BOOT_IMAGE
  135. case IMAGE_FORMAT_ANDROID:
  136. images.os.type = IH_TYPE_KERNEL;
  137. images.os.comp = android_image_get_kcomp(os_hdr);
  138. images.os.os = IH_OS_LINUX;
  139. images.os.end = android_image_get_end(os_hdr);
  140. images.os.load = android_image_get_kload(os_hdr);
  141. images.ep = images.os.load;
  142. ep_found = true;
  143. break;
  144. #endif
  145. default:
  146. puts("ERROR: unknown image format type!\n");
  147. return 1;
  148. }
  149. /* If we have a valid setup.bin, we will use that for entry (x86) */
  150. if (images.os.arch == IH_ARCH_I386 ||
  151. images.os.arch == IH_ARCH_X86_64) {
  152. ulong len;
  153. ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
  154. if (ret < 0 && ret != -ENOENT) {
  155. puts("Could not find a valid setup.bin for x86\n");
  156. return 1;
  157. }
  158. /* Kernel entry point is the setup.bin */
  159. } else if (images.legacy_hdr_valid) {
  160. images.ep = image_get_ep(&images.legacy_hdr_os_copy);
  161. #if IMAGE_ENABLE_FIT
  162. } else if (images.fit_uname_os) {
  163. int ret;
  164. ret = fit_image_get_entry(images.fit_hdr_os,
  165. images.fit_noffset_os, &images.ep);
  166. if (ret) {
  167. puts("Can't get entry point property!\n");
  168. return 1;
  169. }
  170. #endif
  171. } else if (!ep_found) {
  172. puts("Could not find kernel entry point!\n");
  173. return 1;
  174. }
  175. if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
  176. if (CONFIG_IS_ENABLED(CMD_BOOTI) &&
  177. images.os.arch == IH_ARCH_ARM64) {
  178. ulong image_addr;
  179. ulong image_size;
  180. ret = booti_setup(images.os.image_start, &image_addr,
  181. &image_size, true);
  182. if (ret != 0)
  183. return 1;
  184. images.os.type = IH_TYPE_KERNEL;
  185. images.os.load = image_addr;
  186. images.ep = image_addr;
  187. } else {
  188. images.os.load = images.os.image_start;
  189. images.ep += images.os.image_start;
  190. }
  191. }
  192. images.os.start = map_to_sysmem(os_hdr);
  193. return 0;
  194. }
  195. /**
  196. * bootm_find_images - wrapper to find and locate various images
  197. * @flag: Ignored Argument
  198. * @argc: command argument count
  199. * @argv: command argument list
  200. * @start: OS image start address
  201. * @size: OS image size
  202. *
  203. * boot_find_images() will attempt to load an available ramdisk,
  204. * flattened device tree, as well as specifically marked
  205. * "loadable" images (loadables are FIT only)
  206. *
  207. * Note: bootm_find_images will skip an image if it is not found
  208. *
  209. * @return:
  210. * 0, if all existing images were loaded correctly
  211. * 1, if an image is found but corrupted, or invalid
  212. */
  213. int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
  214. ulong size)
  215. {
  216. int ret;
  217. /* find ramdisk */
  218. ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
  219. &images.rd_start, &images.rd_end);
  220. if (ret) {
  221. puts("Ramdisk image is corrupt or invalid\n");
  222. return 1;
  223. }
  224. /* check if ramdisk overlaps OS image */
  225. if (images.rd_start && (((ulong)images.rd_start >= start &&
  226. (ulong)images.rd_start < start + size) ||
  227. ((ulong)images.rd_end > start &&
  228. (ulong)images.rd_end <= start + size) ||
  229. ((ulong)images.rd_start < start &&
  230. (ulong)images.rd_end >= start + size))) {
  231. printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
  232. start, start + size);
  233. return 1;
  234. }
  235. #if IMAGE_ENABLE_OF_LIBFDT
  236. /* find flattened device tree */
  237. ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
  238. &images.ft_addr, &images.ft_len);
  239. if (ret) {
  240. puts("Could not find a valid device tree\n");
  241. return 1;
  242. }
  243. /* check if FDT overlaps OS image */
  244. if (images.ft_addr &&
  245. (((ulong)images.ft_addr >= start &&
  246. (ulong)images.ft_addr <= start + size) ||
  247. ((ulong)images.ft_addr + images.ft_len >= start &&
  248. (ulong)images.ft_addr + images.ft_len <= start + size))) {
  249. printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
  250. start, start + size);
  251. return 1;
  252. }
  253. if (CONFIG_IS_ENABLED(CMD_FDT))
  254. set_working_fdt_addr(map_to_sysmem(images.ft_addr));
  255. #endif
  256. #if IMAGE_ENABLE_FIT
  257. #if defined(CONFIG_FPGA)
  258. /* find bitstreams */
  259. ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
  260. NULL, NULL);
  261. if (ret) {
  262. printf("FPGA image is corrupted or invalid\n");
  263. return 1;
  264. }
  265. #endif
  266. /* find all of the loadables */
  267. ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
  268. NULL, NULL);
  269. if (ret) {
  270. printf("Loadable(s) is corrupt or invalid\n");
  271. return 1;
  272. }
  273. #endif
  274. return 0;
  275. }
  276. static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
  277. char *const argv[])
  278. {
  279. if (((images.os.type == IH_TYPE_KERNEL) ||
  280. (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
  281. (images.os.type == IH_TYPE_MULTI)) &&
  282. (images.os.os == IH_OS_LINUX ||
  283. images.os.os == IH_OS_VXWORKS))
  284. return bootm_find_images(flag, argc, argv, 0, 0);
  285. return 0;
  286. }
  287. #endif /* USE_HOSTC */
  288. #if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
  289. /**
  290. * handle_decomp_error() - display a decompression error
  291. *
  292. * This function tries to produce a useful message. In the case where the
  293. * uncompressed size is the same as the available space, we can assume that
  294. * the image is too large for the buffer.
  295. *
  296. * @comp_type: Compression type being used (IH_COMP_...)
  297. * @uncomp_size: Number of bytes uncompressed
  298. * @ret: errno error code received from compression library
  299. * @return Appropriate BOOTM_ERR_ error code
  300. */
  301. static int handle_decomp_error(int comp_type, size_t uncomp_size, int ret)
  302. {
  303. const char *name = genimg_get_comp_name(comp_type);
  304. /* ENOSYS means unimplemented compression type, don't reset. */
  305. if (ret == -ENOSYS)
  306. return BOOTM_ERR_UNIMPLEMENTED;
  307. if (uncomp_size >= CONFIG_SYS_BOOTM_LEN)
  308. printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
  309. else
  310. printf("%s: uncompress error %d\n", name, ret);
  311. /*
  312. * The decompression routines are now safe, so will not write beyond
  313. * their bounds. Probably it is not necessary to reset, but maintain
  314. * the current behaviour for now.
  315. */
  316. printf("Must RESET board to recover\n");
  317. #ifndef USE_HOSTCC
  318. bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  319. #endif
  320. return BOOTM_ERR_RESET;
  321. }
  322. #endif
  323. #ifndef USE_HOSTCC
  324. static int bootm_load_os(bootm_headers_t *images, int boot_progress)
  325. {
  326. image_info_t os = images->os;
  327. ulong load = os.load;
  328. ulong load_end;
  329. ulong blob_start = os.start;
  330. ulong blob_end = os.end;
  331. ulong image_start = os.image_start;
  332. ulong image_len = os.image_len;
  333. ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
  334. bool no_overlap;
  335. void *load_buf, *image_buf;
  336. int err;
  337. load_buf = map_sysmem(load, 0);
  338. image_buf = map_sysmem(os.image_start, image_len);
  339. err = image_decomp(os.comp, load, os.image_start, os.type,
  340. load_buf, image_buf, image_len,
  341. CONFIG_SYS_BOOTM_LEN, &load_end);
  342. if (err) {
  343. err = handle_decomp_error(os.comp, load_end - load, err);
  344. bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  345. return err;
  346. }
  347. /* We need the decompressed image size in the next steps */
  348. images->os.image_len = load_end - load;
  349. flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start);
  350. debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
  351. bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
  352. no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
  353. if (!no_overlap && load < blob_end && load_end > blob_start) {
  354. debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
  355. blob_start, blob_end);
  356. debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
  357. load_end);
  358. /* Check what type of image this is. */
  359. if (images->legacy_hdr_valid) {
  360. if (image_get_type(&images->legacy_hdr_os_copy)
  361. == IH_TYPE_MULTI)
  362. puts("WARNING: legacy format multi component image overwritten\n");
  363. return BOOTM_ERR_OVERLAP;
  364. } else {
  365. puts("ERROR: new format image overwritten - must RESET the board to recover\n");
  366. bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
  367. return BOOTM_ERR_RESET;
  368. }
  369. }
  370. lmb_reserve(&images->lmb, images->os.load, (load_end -
  371. images->os.load));
  372. return 0;
  373. }
  374. /**
  375. * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
  376. *
  377. * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
  378. * enabled)
  379. */
  380. ulong bootm_disable_interrupts(void)
  381. {
  382. ulong iflag;
  383. /*
  384. * We have reached the point of no return: we are going to
  385. * overwrite all exception vector code, so we cannot easily
  386. * recover from any failures any more...
  387. */
  388. iflag = disable_interrupts();
  389. #ifdef CONFIG_NETCONSOLE
  390. /* Stop the ethernet stack if NetConsole could have left it up */
  391. eth_halt();
  392. # ifndef CONFIG_DM_ETH
  393. eth_unregister(eth_get_dev());
  394. # endif
  395. #endif
  396. #if defined(CONFIG_CMD_USB)
  397. /*
  398. * turn off USB to prevent the host controller from writing to the
  399. * SDRAM while Linux is booting. This could happen (at least for OHCI
  400. * controller), because the HCCA (Host Controller Communication Area)
  401. * lies within the SDRAM and the host controller writes continously to
  402. * this area (as busmaster!). The HccaFrameNumber is for example
  403. * updated every 1 ms within the HCCA structure in SDRAM! For more
  404. * details see the OpenHCI specification.
  405. */
  406. usb_stop();
  407. #endif
  408. return iflag;
  409. }
  410. #define CONSOLE_ARG "console="
  411. #define CONSOLE_ARG_SIZE sizeof(CONSOLE_ARG)
  412. /**
  413. * fixup_silent_linux() - Handle silencing the linux boot if required
  414. *
  415. * This uses the silent_linux envvar to control whether to add/set a "console="
  416. * parameter to the command line
  417. *
  418. * @buf: Buffer containing the string to process
  419. * @maxlen: Maximum length of buffer
  420. * @return 0 if OK, -ENOSPC if @maxlen is too small
  421. */
  422. static int fixup_silent_linux(char *buf, int maxlen)
  423. {
  424. int want_silent;
  425. char *cmdline;
  426. int size;
  427. /*
  428. * Move the input string to the end of buffer. The output string will be
  429. * built up at the start.
  430. */
  431. size = strlen(buf) + 1;
  432. if (size * 2 > maxlen)
  433. return -ENOSPC;
  434. cmdline = buf + maxlen - size;
  435. memmove(cmdline, buf, size);
  436. /*
  437. * Only fix cmdline when requested. The environment variable can be:
  438. *
  439. * no - we never fixup
  440. * yes - we always fixup
  441. * unset - we rely on the console silent flag
  442. */
  443. want_silent = env_get_yesno("silent_linux");
  444. if (want_silent == 0)
  445. return 0;
  446. else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
  447. return 0;
  448. debug("before silent fix-up: %s\n", cmdline);
  449. if (*cmdline) {
  450. char *start = strstr(cmdline, CONSOLE_ARG);
  451. /* Check space for maximum possible new command line */
  452. if (size + CONSOLE_ARG_SIZE > maxlen)
  453. return -ENOSPC;
  454. if (start) {
  455. char *end = strchr(start, ' ');
  456. int start_bytes;
  457. start_bytes = start - cmdline + CONSOLE_ARG_SIZE - 1;
  458. strncpy(buf, cmdline, start_bytes);
  459. if (end)
  460. strcpy(buf + start_bytes, end);
  461. else
  462. buf[start_bytes] = '\0';
  463. } else {
  464. sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
  465. }
  466. if (buf + strlen(buf) >= cmdline)
  467. return -ENOSPC;
  468. } else {
  469. if (maxlen < sizeof(CONSOLE_ARG))
  470. return -ENOSPC;
  471. strcpy(buf, CONSOLE_ARG);
  472. }
  473. debug("after silent fix-up: %s\n", buf);
  474. return 0;
  475. }
  476. /**
  477. * process_subst() - Handle substitution of ${...} fields in the environment
  478. *
  479. * Handle variable substitution in the provided buffer
  480. *
  481. * @buf: Buffer containing the string to process
  482. * @maxlen: Maximum length of buffer
  483. * @return 0 if OK, -ENOSPC if @maxlen is too small
  484. */
  485. static int process_subst(char *buf, int maxlen)
  486. {
  487. char *cmdline;
  488. int size;
  489. int ret;
  490. /* Move to end of buffer */
  491. size = strlen(buf) + 1;
  492. cmdline = buf + maxlen - size;
  493. if (buf + size > cmdline)
  494. return -ENOSPC;
  495. memmove(cmdline, buf, size);
  496. ret = cli_simple_process_macros(cmdline, buf, cmdline - buf);
  497. return ret;
  498. }
  499. int bootm_process_cmdline(char *buf, int maxlen, int flags)
  500. {
  501. int ret;
  502. /* Check config first to enable compiler to eliminate code */
  503. if (IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
  504. !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) &&
  505. (flags & BOOTM_CL_SILENT)) {
  506. ret = fixup_silent_linux(buf, maxlen);
  507. if (ret)
  508. return log_msg_ret("silent", ret);
  509. }
  510. if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
  511. (flags & BOOTM_CL_SUBST)) {
  512. ret = process_subst(buf, maxlen);
  513. if (ret)
  514. return log_msg_ret("subst", ret);
  515. }
  516. return 0;
  517. }
  518. int bootm_process_cmdline_env(int flags)
  519. {
  520. const int maxlen = MAX_CMDLINE_SIZE;
  521. bool do_silent;
  522. const char *env;
  523. char *buf;
  524. int ret;
  525. /* First check if any action is needed */
  526. do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
  527. !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
  528. if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
  529. return 0;
  530. env = env_get("bootargs");
  531. if (env && strlen(env) >= maxlen)
  532. return -E2BIG;
  533. buf = malloc(maxlen);
  534. if (!buf)
  535. return -ENOMEM;
  536. if (env)
  537. strcpy(buf, env);
  538. else
  539. *buf = '\0';
  540. ret = bootm_process_cmdline(buf, maxlen, flags);
  541. if (!ret) {
  542. ret = env_set("bootargs", buf);
  543. /*
  544. * If buf is "" and bootargs does not exist, this will produce
  545. * an error trying to delete bootargs. Ignore it
  546. */
  547. if (ret == -ENOENT)
  548. ret = 0;
  549. }
  550. free(buf);
  551. if (ret)
  552. return log_msg_ret("env", ret);
  553. return 0;
  554. }
  555. /**
  556. * Execute selected states of the bootm command.
  557. *
  558. * Note the arguments to this state must be the first argument, Any 'bootm'
  559. * or sub-command arguments must have already been taken.
  560. *
  561. * Note that if states contains more than one flag it MUST contain
  562. * BOOTM_STATE_START, since this handles and consumes the command line args.
  563. *
  564. * Also note that aside from boot_os_fn functions and bootm_load_os no other
  565. * functions we store the return value of in 'ret' may use a negative return
  566. * value, without special handling.
  567. *
  568. * @param cmdtp Pointer to bootm command table entry
  569. * @param flag Command flags (CMD_FLAG_...)
  570. * @param argc Number of subcommand arguments (0 = no arguments)
  571. * @param argv Arguments
  572. * @param states Mask containing states to run (BOOTM_STATE_...)
  573. * @param images Image header information
  574. * @param boot_progress 1 to show boot progress, 0 to not do this
  575. * @return 0 if ok, something else on error. Some errors will cause this
  576. * function to perform a reboot! If states contains BOOTM_STATE_OS_GO
  577. * then the intent is to boot an OS, so this function will not return
  578. * unless the image type is standalone.
  579. */
  580. int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
  581. char *const argv[], int states, bootm_headers_t *images,
  582. int boot_progress)
  583. {
  584. boot_os_fn *boot_fn;
  585. ulong iflag = 0;
  586. int ret = 0, need_boot_fn;
  587. images->state |= states;
  588. /*
  589. * Work through the states and see how far we get. We stop on
  590. * any error.
  591. */
  592. if (states & BOOTM_STATE_START)
  593. ret = bootm_start(cmdtp, flag, argc, argv);
  594. if (!ret && (states & BOOTM_STATE_FINDOS))
  595. ret = bootm_find_os(cmdtp, flag, argc, argv);
  596. if (!ret && (states & BOOTM_STATE_FINDOTHER))
  597. ret = bootm_find_other(cmdtp, flag, argc, argv);
  598. /* Load the OS */
  599. if (!ret && (states & BOOTM_STATE_LOADOS)) {
  600. iflag = bootm_disable_interrupts();
  601. ret = bootm_load_os(images, 0);
  602. if (ret && ret != BOOTM_ERR_OVERLAP)
  603. goto err;
  604. else if (ret == BOOTM_ERR_OVERLAP)
  605. ret = 0;
  606. }
  607. /* Relocate the ramdisk */
  608. #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
  609. if (!ret && (states & BOOTM_STATE_RAMDISK)) {
  610. ulong rd_len = images->rd_end - images->rd_start;
  611. ret = boot_ramdisk_high(&images->lmb, images->rd_start,
  612. rd_len, &images->initrd_start, &images->initrd_end);
  613. if (!ret) {
  614. env_set_hex("initrd_start", images->initrd_start);
  615. env_set_hex("initrd_end", images->initrd_end);
  616. }
  617. }
  618. #endif
  619. #if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
  620. if (!ret && (states & BOOTM_STATE_FDT)) {
  621. boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
  622. ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
  623. &images->ft_len);
  624. }
  625. #endif
  626. /* From now on, we need the OS boot function */
  627. if (ret)
  628. return ret;
  629. boot_fn = bootm_os_get_boot_func(images->os.os);
  630. need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
  631. BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
  632. BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
  633. if (boot_fn == NULL && need_boot_fn) {
  634. if (iflag)
  635. enable_interrupts();
  636. printf("ERROR: booting os '%s' (%d) is not supported\n",
  637. genimg_get_os_name(images->os.os), images->os.os);
  638. bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
  639. return 1;
  640. }
  641. /* Call various other states that are not generally used */
  642. if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
  643. ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
  644. if (!ret && (states & BOOTM_STATE_OS_BD_T))
  645. ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
  646. if (!ret && (states & BOOTM_STATE_OS_PREP)) {
  647. ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
  648. if (ret) {
  649. printf("Cmdline setup failed (err=%d)\n", ret);
  650. ret = CMD_RET_FAILURE;
  651. goto err;
  652. }
  653. ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
  654. }
  655. #ifdef CONFIG_TRACE
  656. /* Pretend to run the OS, then run a user command */
  657. if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
  658. char *cmd_list = env_get("fakegocmd");
  659. ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
  660. images, boot_fn);
  661. if (!ret && cmd_list)
  662. ret = run_command_list(cmd_list, -1, flag);
  663. }
  664. #endif
  665. /* Check for unsupported subcommand. */
  666. if (ret) {
  667. puts("subcommand not supported\n");
  668. return ret;
  669. }
  670. /* Now run the OS! We hope this doesn't return */
  671. if (!ret && (states & BOOTM_STATE_OS_GO))
  672. ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
  673. images, boot_fn);
  674. /* Deal with any fallout */
  675. err:
  676. if (iflag)
  677. enable_interrupts();
  678. if (ret == BOOTM_ERR_UNIMPLEMENTED)
  679. bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
  680. else if (ret == BOOTM_ERR_RESET)
  681. do_reset(cmdtp, flag, argc, argv);
  682. return ret;
  683. }
  684. #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
  685. /**
  686. * image_get_kernel - verify legacy format kernel image
  687. * @img_addr: in RAM address of the legacy format image to be verified
  688. * @verify: data CRC verification flag
  689. *
  690. * image_get_kernel() verifies legacy image integrity and returns pointer to
  691. * legacy image header if image verification was completed successfully.
  692. *
  693. * returns:
  694. * pointer to a legacy image header if valid image was found
  695. * otherwise return NULL
  696. */
  697. static image_header_t *image_get_kernel(ulong img_addr, int verify)
  698. {
  699. image_header_t *hdr = (image_header_t *)img_addr;
  700. if (!image_check_magic(hdr)) {
  701. puts("Bad Magic Number\n");
  702. bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
  703. return NULL;
  704. }
  705. bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
  706. if (!image_check_hcrc(hdr)) {
  707. puts("Bad Header Checksum\n");
  708. bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
  709. return NULL;
  710. }
  711. bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
  712. image_print_contents(hdr);
  713. if (verify) {
  714. puts(" Verifying Checksum ... ");
  715. if (!image_check_dcrc(hdr)) {
  716. printf("Bad Data CRC\n");
  717. bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
  718. return NULL;
  719. }
  720. puts("OK\n");
  721. }
  722. bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
  723. if (!image_check_target_arch(hdr)) {
  724. printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
  725. bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
  726. return NULL;
  727. }
  728. return hdr;
  729. }
  730. #endif
  731. /**
  732. * boot_get_kernel - find kernel image
  733. * @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. *
  736. * boot_get_kernel() tries to find a kernel image, verifies its integrity
  737. * 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. */
  743. static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
  744. char *const argv[], bootm_headers_t *images,
  745. ulong *os_data, ulong *os_len)
  746. {
  747. #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
  748. image_header_t *hdr;
  749. #endif
  750. ulong img_addr;
  751. const void *buf;
  752. const char *fit_uname_config = NULL;
  753. const char *fit_uname_kernel = NULL;
  754. #if IMAGE_ENABLE_FIT
  755. int os_noffset;
  756. #endif
  757. img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
  758. &fit_uname_config,
  759. &fit_uname_kernel);
  760. bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
  761. /* check image type, for FIT images get FIT kernel node */
  762. *os_data = *os_len = 0;
  763. buf = map_sysmem(img_addr, 0);
  764. switch (genimg_get_format(buf)) {
  765. #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
  766. case IMAGE_FORMAT_LEGACY:
  767. printf("## Booting kernel from Legacy Image at %08lx ...\n",
  768. img_addr);
  769. hdr = image_get_kernel(img_addr, images->verify);
  770. if (!hdr)
  771. return NULL;
  772. bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
  773. /* get os_data and os_len */
  774. switch (image_get_type(hdr)) {
  775. case IH_TYPE_KERNEL:
  776. case IH_TYPE_KERNEL_NOLOAD:
  777. *os_data = image_get_data(hdr);
  778. *os_len = image_get_data_size(hdr);
  779. break;
  780. case IH_TYPE_MULTI:
  781. image_multi_getimg(hdr, 0, os_data, os_len);
  782. break;
  783. case IH_TYPE_STANDALONE:
  784. *os_data = image_get_data(hdr);
  785. *os_len = image_get_data_size(hdr);
  786. break;
  787. default:
  788. printf("Wrong Image Type for %s command\n",
  789. cmdtp->name);
  790. bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
  791. return NULL;
  792. }
  793. /*
  794. * copy image header to allow for image overwrites during
  795. * kernel decompression.
  796. */
  797. memmove(&images->legacy_hdr_os_copy, hdr,
  798. sizeof(image_header_t));
  799. /* save pointer to image header */
  800. images->legacy_hdr_os = hdr;
  801. images->legacy_hdr_valid = 1;
  802. bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
  803. break;
  804. #endif
  805. #if IMAGE_ENABLE_FIT
  806. case IMAGE_FORMAT_FIT:
  807. os_noffset = fit_image_load(images, img_addr,
  808. &fit_uname_kernel, &fit_uname_config,
  809. IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
  810. BOOTSTAGE_ID_FIT_KERNEL_START,
  811. FIT_LOAD_IGNORED, os_data, os_len);
  812. if (os_noffset < 0)
  813. return NULL;
  814. images->fit_hdr_os = map_sysmem(img_addr, 0);
  815. images->fit_uname_os = fit_uname_kernel;
  816. images->fit_uname_cfg = fit_uname_config;
  817. images->fit_noffset_os = os_noffset;
  818. break;
  819. #endif
  820. #ifdef CONFIG_ANDROID_BOOT_IMAGE
  821. case IMAGE_FORMAT_ANDROID:
  822. printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
  823. if (android_image_get_kernel(buf, images->verify,
  824. os_data, os_len))
  825. return NULL;
  826. break;
  827. #endif
  828. default:
  829. printf("Wrong Image Format for %s command\n", cmdtp->name);
  830. bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
  831. return NULL;
  832. }
  833. debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
  834. *os_data, *os_len, *os_len);
  835. return buf;
  836. }
  837. /**
  838. * switch_to_non_secure_mode() - switch to non-secure mode
  839. *
  840. * This routine is overridden by architectures requiring this feature.
  841. */
  842. void __weak switch_to_non_secure_mode(void)
  843. {
  844. }
  845. #else /* USE_HOSTCC */
  846. #if defined(CONFIG_FIT_SIGNATURE)
  847. static int bootm_host_load_image(const void *fit, int req_image_type,
  848. int cfg_noffset)
  849. {
  850. const char *fit_uname_config = NULL;
  851. ulong data, len;
  852. bootm_headers_t images;
  853. int noffset;
  854. ulong load_end;
  855. uint8_t image_type;
  856. uint8_t imape_comp;
  857. void *load_buf;
  858. int ret;
  859. fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
  860. memset(&images, '\0', sizeof(images));
  861. images.verify = 1;
  862. noffset = fit_image_load(&images, (ulong)fit,
  863. NULL, &fit_uname_config,
  864. IH_ARCH_DEFAULT, req_image_type, -1,
  865. FIT_LOAD_IGNORED, &data, &len);
  866. if (noffset < 0)
  867. return noffset;
  868. if (fit_image_get_type(fit, noffset, &image_type)) {
  869. puts("Can't get image type!\n");
  870. return -EINVAL;
  871. }
  872. if (fit_image_get_comp(fit, noffset, &imape_comp)) {
  873. puts("Can't get image compression!\n");
  874. return -EINVAL;
  875. }
  876. /* Allow the image to expand by a factor of 4, should be safe */
  877. load_buf = malloc((1 << 20) + len * 4);
  878. ret = image_decomp(imape_comp, 0, data, image_type, load_buf,
  879. (void *)data, len, CONFIG_SYS_BOOTM_LEN,
  880. &load_end);
  881. free(load_buf);
  882. if (ret) {
  883. ret = handle_decomp_error(imape_comp, load_end - 0, ret);
  884. if (ret != BOOTM_ERR_UNIMPLEMENTED)
  885. return ret;
  886. }
  887. return 0;
  888. }
  889. int bootm_host_load_images(const void *fit, int cfg_noffset)
  890. {
  891. static uint8_t image_types[] = {
  892. IH_TYPE_KERNEL,
  893. IH_TYPE_FLATDT,
  894. IH_TYPE_RAMDISK,
  895. };
  896. int err = 0;
  897. int i;
  898. for (i = 0; i < ARRAY_SIZE(image_types); i++) {
  899. int ret;
  900. ret = bootm_host_load_image(fit, image_types[i], cfg_noffset);
  901. if (!err && ret && ret != -ENOENT)
  902. err = ret;
  903. }
  904. /* Return the first error we found */
  905. return err;
  906. }
  907. #endif
  908. #endif /* ndef USE_HOSTCC */