image-board.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Image code used by boards (and not host tools)
  4. *
  5. * (C) Copyright 2008 Semihalf
  6. *
  7. * (C) Copyright 2000-2006
  8. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  9. */
  10. #include <common.h>
  11. #include <bootstage.h>
  12. #include <cpu_func.h>
  13. #include <display_options.h>
  14. #include <env.h>
  15. #include <fpga.h>
  16. #include <image.h>
  17. #include <init.h>
  18. #include <log.h>
  19. #include <mapmem.h>
  20. #include <rtc.h>
  21. #include <watchdog.h>
  22. #include <asm/cache.h>
  23. #include <asm/global_data.h>
  24. DECLARE_GLOBAL_DATA_PTR;
  25. /**
  26. * image_get_ramdisk - get and verify ramdisk image
  27. * @rd_addr: ramdisk image start address
  28. * @arch: expected ramdisk architecture
  29. * @verify: checksum verification flag
  30. *
  31. * image_get_ramdisk() returns a pointer to the verified ramdisk image
  32. * header. Routine receives image start address and expected architecture
  33. * flag. Verification done covers data and header integrity and os/type/arch
  34. * fields checking.
  35. *
  36. * returns:
  37. * pointer to a ramdisk image header, if image was found and valid
  38. * otherwise, return NULL
  39. */
  40. static const struct legacy_img_hdr *image_get_ramdisk(ulong rd_addr, u8 arch,
  41. int verify)
  42. {
  43. const struct legacy_img_hdr *rd_hdr = (const struct legacy_img_hdr *)rd_addr;
  44. if (!image_check_magic(rd_hdr)) {
  45. puts("Bad Magic Number\n");
  46. bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
  47. return NULL;
  48. }
  49. if (!image_check_hcrc(rd_hdr)) {
  50. puts("Bad Header Checksum\n");
  51. bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
  52. return NULL;
  53. }
  54. bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
  55. image_print_contents(rd_hdr);
  56. if (verify) {
  57. puts(" Verifying Checksum ... ");
  58. if (!image_check_dcrc(rd_hdr)) {
  59. puts("Bad Data CRC\n");
  60. bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
  61. return NULL;
  62. }
  63. puts("OK\n");
  64. }
  65. bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
  66. if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
  67. !image_check_arch(rd_hdr, arch) ||
  68. !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
  69. printf("No Linux %s Ramdisk Image\n",
  70. genimg_get_arch_name(arch));
  71. bootstage_error(BOOTSTAGE_ID_RAMDISK);
  72. return NULL;
  73. }
  74. return rd_hdr;
  75. }
  76. /*****************************************************************************/
  77. /* Shared dual-format routines */
  78. /*****************************************************************************/
  79. ulong image_load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
  80. ulong image_save_addr; /* Default Save Address */
  81. ulong image_save_size; /* Default Save Size (in bytes) */
  82. static int on_loadaddr(const char *name, const char *value, enum env_op op,
  83. int flags)
  84. {
  85. switch (op) {
  86. case env_op_create:
  87. case env_op_overwrite:
  88. image_load_addr = hextoul(value, NULL);
  89. break;
  90. default:
  91. break;
  92. }
  93. return 0;
  94. }
  95. U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
  96. ulong env_get_bootm_low(void)
  97. {
  98. char *s = env_get("bootm_low");
  99. if (s) {
  100. ulong tmp = hextoul(s, NULL);
  101. return tmp;
  102. }
  103. #if defined(CFG_SYS_SDRAM_BASE)
  104. return CFG_SYS_SDRAM_BASE;
  105. #elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_RISCV)
  106. return gd->bd->bi_dram[0].start;
  107. #else
  108. return 0;
  109. #endif
  110. }
  111. phys_size_t env_get_bootm_size(void)
  112. {
  113. phys_size_t tmp, size;
  114. phys_addr_t start;
  115. char *s = env_get("bootm_size");
  116. if (s) {
  117. tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
  118. return tmp;
  119. }
  120. start = gd->ram_base;
  121. size = gd->ram_size;
  122. if (start + size > gd->ram_top)
  123. size = gd->ram_top - start;
  124. s = env_get("bootm_low");
  125. if (s)
  126. tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
  127. else
  128. tmp = start;
  129. return size - (tmp - start);
  130. }
  131. phys_size_t env_get_bootm_mapsize(void)
  132. {
  133. phys_size_t tmp;
  134. char *s = env_get("bootm_mapsize");
  135. if (s) {
  136. tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
  137. return tmp;
  138. }
  139. #if defined(CFG_SYS_BOOTMAPSZ)
  140. return CFG_SYS_BOOTMAPSZ;
  141. #else
  142. return env_get_bootm_size();
  143. #endif
  144. }
  145. void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
  146. {
  147. if (to == from)
  148. return;
  149. if (IS_ENABLED(CONFIG_HW_WATCHDOG) || IS_ENABLED(CONFIG_WATCHDOG)) {
  150. if (to > from) {
  151. from += len;
  152. to += len;
  153. }
  154. while (len > 0) {
  155. size_t tail = (len > chunksz) ? chunksz : len;
  156. schedule();
  157. if (to > from) {
  158. to -= tail;
  159. from -= tail;
  160. }
  161. memmove(to, from, tail);
  162. if (to < from) {
  163. to += tail;
  164. from += tail;
  165. }
  166. len -= tail;
  167. }
  168. } else {
  169. memmove(to, from, len);
  170. }
  171. }
  172. /**
  173. * genimg_get_kernel_addr_fit - get the real kernel address and return 2
  174. * FIT strings
  175. * @img_addr: a string might contain real image address
  176. * @fit_uname_config: double pointer to a char, will hold pointer to a
  177. * configuration unit name
  178. * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
  179. * name
  180. *
  181. * genimg_get_kernel_addr_fit get the real kernel start address from a string
  182. * which is normally the first argv of bootm/bootz
  183. *
  184. * returns:
  185. * kernel start address
  186. */
  187. ulong genimg_get_kernel_addr_fit(char * const img_addr,
  188. const char **fit_uname_config,
  189. const char **fit_uname_kernel)
  190. {
  191. ulong kernel_addr;
  192. /* find out kernel image address */
  193. if (!img_addr) {
  194. kernel_addr = image_load_addr;
  195. debug("* kernel: default image load address = 0x%08lx\n",
  196. image_load_addr);
  197. } else if (CONFIG_IS_ENABLED(FIT) &&
  198. fit_parse_conf(img_addr, image_load_addr, &kernel_addr,
  199. fit_uname_config)) {
  200. debug("* kernel: config '%s' from image at 0x%08lx\n",
  201. *fit_uname_config, kernel_addr);
  202. } else if (CONFIG_IS_ENABLED(FIT) &&
  203. fit_parse_subimage(img_addr, image_load_addr, &kernel_addr,
  204. fit_uname_kernel)) {
  205. debug("* kernel: subimage '%s' from image at 0x%08lx\n",
  206. *fit_uname_kernel, kernel_addr);
  207. } else {
  208. kernel_addr = hextoul(img_addr, NULL);
  209. debug("* kernel: cmdline image address = 0x%08lx\n",
  210. kernel_addr);
  211. }
  212. return kernel_addr;
  213. }
  214. /**
  215. * genimg_get_kernel_addr() is the simple version of
  216. * genimg_get_kernel_addr_fit(). It ignores those return FIT strings
  217. */
  218. ulong genimg_get_kernel_addr(char * const img_addr)
  219. {
  220. const char *fit_uname_config = NULL;
  221. const char *fit_uname_kernel = NULL;
  222. return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
  223. &fit_uname_kernel);
  224. }
  225. /**
  226. * genimg_get_format - get image format type
  227. * @img_addr: image start address
  228. *
  229. * genimg_get_format() checks whether provided address points to a valid
  230. * legacy or FIT image.
  231. *
  232. * New uImage format and FDT blob are based on a libfdt. FDT blob
  233. * may be passed directly or embedded in a FIT image. In both situations
  234. * genimg_get_format() must be able to dectect libfdt header.
  235. *
  236. * returns:
  237. * image format type or IMAGE_FORMAT_INVALID if no image is present
  238. */
  239. int genimg_get_format(const void *img_addr)
  240. {
  241. if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
  242. const struct legacy_img_hdr *hdr;
  243. hdr = (const struct legacy_img_hdr *)img_addr;
  244. if (image_check_magic(hdr))
  245. return IMAGE_FORMAT_LEGACY;
  246. }
  247. if (CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)) {
  248. if (!fdt_check_header(img_addr))
  249. return IMAGE_FORMAT_FIT;
  250. }
  251. if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) &&
  252. is_android_boot_image_header(img_addr))
  253. return IMAGE_FORMAT_ANDROID;
  254. return IMAGE_FORMAT_INVALID;
  255. }
  256. /**
  257. * fit_has_config - check if there is a valid FIT configuration
  258. * @images: pointer to the bootm command headers structure
  259. *
  260. * fit_has_config() checks if there is a FIT configuration in use
  261. * (if FTI support is present).
  262. *
  263. * returns:
  264. * 0, no FIT support or no configuration found
  265. * 1, configuration found
  266. */
  267. int genimg_has_config(struct bootm_headers *images)
  268. {
  269. if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg)
  270. return 1;
  271. return 0;
  272. }
  273. /**
  274. * select_ramdisk() - Select and locate the ramdisk to use
  275. *
  276. * @images: pointer to the bootm images structure
  277. * @select: name of ramdisk to select, or hex address, NULL for any
  278. * @arch: expected ramdisk architecture
  279. * @rd_datap: pointer to a ulong variable, will hold ramdisk pointer
  280. * @rd_lenp: pointer to a ulong variable, will hold ramdisk length
  281. * Return: 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported),
  282. * other -ve value on other error
  283. */
  284. static int select_ramdisk(struct bootm_headers *images, const char *select, u8 arch,
  285. ulong *rd_datap, ulong *rd_lenp)
  286. {
  287. const char *fit_uname_config;
  288. const char *fit_uname_ramdisk;
  289. bool done_select = !select;
  290. bool done = false;
  291. int rd_noffset;
  292. ulong rd_addr = 0;
  293. char *buf;
  294. if (CONFIG_IS_ENABLED(FIT)) {
  295. fit_uname_config = images->fit_uname_cfg;
  296. fit_uname_ramdisk = NULL;
  297. if (select) {
  298. ulong default_addr;
  299. /*
  300. * If the init ramdisk comes from the FIT image and
  301. * the FIT image address is omitted in the command
  302. * line argument, try to use os FIT image address or
  303. * default load address.
  304. */
  305. if (images->fit_uname_os)
  306. default_addr = (ulong)images->fit_hdr_os;
  307. else
  308. default_addr = image_load_addr;
  309. if (fit_parse_conf(select, default_addr, &rd_addr,
  310. &fit_uname_config)) {
  311. debug("* ramdisk: config '%s' from image at 0x%08lx\n",
  312. fit_uname_config, rd_addr);
  313. done_select = true;
  314. } else if (fit_parse_subimage(select, default_addr,
  315. &rd_addr,
  316. &fit_uname_ramdisk)) {
  317. debug("* ramdisk: subimage '%s' from image at 0x%08lx\n",
  318. fit_uname_ramdisk, rd_addr);
  319. done_select = true;
  320. }
  321. }
  322. }
  323. if (!done_select) {
  324. rd_addr = hextoul(select, NULL);
  325. debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr);
  326. }
  327. if (CONFIG_IS_ENABLED(FIT) && !select) {
  328. /* use FIT configuration provided in first bootm
  329. * command argument. If the property is not defined,
  330. * quit silently (with -ENOPKG)
  331. */
  332. rd_addr = map_to_sysmem(images->fit_hdr_os);
  333. rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
  334. rd_addr);
  335. if (rd_noffset == -ENOENT)
  336. return -ENOPKG;
  337. else if (rd_noffset < 0)
  338. return rd_noffset;
  339. }
  340. /*
  341. * Check if there is an initrd image at the
  342. * address provided in the second bootm argument
  343. * check image type, for FIT images get FIT node.
  344. */
  345. buf = map_sysmem(rd_addr, 0);
  346. switch (genimg_get_format(buf)) {
  347. case IMAGE_FORMAT_LEGACY:
  348. if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
  349. const struct legacy_img_hdr *rd_hdr;
  350. printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
  351. rd_addr);
  352. bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
  353. rd_hdr = image_get_ramdisk(rd_addr, arch,
  354. images->verify);
  355. if (!rd_hdr)
  356. return -ENOENT;
  357. *rd_datap = image_get_data(rd_hdr);
  358. *rd_lenp = image_get_data_size(rd_hdr);
  359. done = true;
  360. }
  361. break;
  362. case IMAGE_FORMAT_FIT:
  363. if (CONFIG_IS_ENABLED(FIT)) {
  364. rd_noffset = fit_image_load(images, rd_addr,
  365. &fit_uname_ramdisk,
  366. &fit_uname_config,
  367. arch, IH_TYPE_RAMDISK,
  368. BOOTSTAGE_ID_FIT_RD_START,
  369. FIT_LOAD_OPTIONAL_NON_ZERO,
  370. rd_datap, rd_lenp);
  371. if (rd_noffset < 0)
  372. return rd_noffset;
  373. images->fit_hdr_rd = map_sysmem(rd_addr, 0);
  374. images->fit_uname_rd = fit_uname_ramdisk;
  375. images->fit_noffset_rd = rd_noffset;
  376. done = true;
  377. }
  378. break;
  379. case IMAGE_FORMAT_ANDROID:
  380. if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
  381. int ret;
  382. if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
  383. void *boot_img = map_sysmem(get_abootimg_addr(), 0);
  384. void *vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
  385. ret = android_image_get_ramdisk(boot_img, vendor_boot_img,
  386. rd_datap, rd_lenp);
  387. unmap_sysmem(vendor_boot_img);
  388. unmap_sysmem(boot_img);
  389. } else {
  390. void *ptr = map_sysmem(images->os.start, 0);
  391. ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp);
  392. unmap_sysmem(ptr);
  393. }
  394. if (ret)
  395. return ret;
  396. done = true;
  397. }
  398. break;
  399. }
  400. if (!done) {
  401. if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
  402. char *end = NULL;
  403. if (select)
  404. end = strchr(select, ':');
  405. if (end) {
  406. *rd_lenp = hextoul(++end, NULL);
  407. *rd_datap = rd_addr;
  408. done = true;
  409. }
  410. }
  411. if (!done) {
  412. puts("Wrong Ramdisk Image Format\n");
  413. return -EINVAL;
  414. }
  415. }
  416. return 0;
  417. }
  418. /**
  419. * boot_get_ramdisk - main ramdisk handling routine
  420. * @argc: command argument count
  421. * @argv: command argument list
  422. * @images: pointer to the bootm images structure
  423. * @arch: expected ramdisk architecture
  424. * @rd_start: pointer to a ulong variable, will hold ramdisk start address
  425. * @rd_end: pointer to a ulong variable, will hold ramdisk end
  426. *
  427. * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
  428. * Currently supported are the following ramdisk sources:
  429. * - multicomponent kernel/ramdisk image,
  430. * - commandline provided address of decicated ramdisk image.
  431. *
  432. * returns:
  433. * 0, if ramdisk image was found and valid, or skiped
  434. * rd_start and rd_end are set to ramdisk start/end addresses if
  435. * ramdisk image is found and valid
  436. *
  437. * 1, if ramdisk image is found but corrupted, or invalid
  438. * rd_start and rd_end are set to 0 if no ramdisk exists
  439. */
  440. int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images,
  441. u8 arch, ulong *rd_start, ulong *rd_end)
  442. {
  443. ulong rd_data, rd_len;
  444. const char *select = NULL;
  445. *rd_start = 0;
  446. *rd_end = 0;
  447. if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
  448. char *buf;
  449. /* Look for an Android boot image */
  450. buf = map_sysmem(images->os.start, 0);
  451. if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
  452. select = (argc == 0) ? env_get("loadaddr") : argv[0];
  453. }
  454. if (argc >= 2)
  455. select = argv[1];
  456. /*
  457. * Look for a '-' which indicates to ignore the
  458. * ramdisk argument
  459. */
  460. if (select && strcmp(select, "-") == 0) {
  461. debug("## Skipping init Ramdisk\n");
  462. rd_len = 0;
  463. rd_data = 0;
  464. } else if (select || genimg_has_config(images)) {
  465. int ret;
  466. ret = select_ramdisk(images, select, arch, &rd_data, &rd_len);
  467. if (ret == -ENOPKG)
  468. return 0;
  469. else if (ret)
  470. return ret;
  471. } else if (images->legacy_hdr_valid &&
  472. image_check_type(&images->legacy_hdr_os_copy,
  473. IH_TYPE_MULTI)) {
  474. /*
  475. * Now check if we have a legacy mult-component image,
  476. * get second entry data start address and len.
  477. */
  478. bootstage_mark(BOOTSTAGE_ID_RAMDISK);
  479. printf("## Loading init Ramdisk from multi component Legacy Image at %08lx ...\n",
  480. (ulong)images->legacy_hdr_os);
  481. image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
  482. } else {
  483. /*
  484. * no initrd image
  485. */
  486. bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
  487. rd_len = 0;
  488. rd_data = 0;
  489. }
  490. if (!rd_data) {
  491. debug("## No init Ramdisk\n");
  492. } else {
  493. *rd_start = rd_data;
  494. *rd_end = rd_data + rd_len;
  495. }
  496. debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
  497. *rd_start, *rd_end);
  498. return 0;
  499. }
  500. /**
  501. * boot_ramdisk_high - relocate init ramdisk
  502. * @lmb: pointer to lmb handle, will be used for memory mgmt
  503. * @rd_data: ramdisk data start address
  504. * @rd_len: ramdisk data length
  505. * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
  506. * start address (after possible relocation)
  507. * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
  508. * end address (after possible relocation)
  509. *
  510. * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
  511. * variable and if requested ramdisk data is moved to a specified location.
  512. *
  513. * Initrd_start and initrd_end are set to final (after relocation) ramdisk
  514. * start/end addresses if ramdisk image start and len were provided,
  515. * otherwise set initrd_start and initrd_end set to zeros.
  516. *
  517. * returns:
  518. * 0 - success
  519. * -1 - failure
  520. */
  521. int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
  522. ulong *initrd_start, ulong *initrd_end)
  523. {
  524. char *s;
  525. ulong initrd_high;
  526. int initrd_copy_to_ram = 1;
  527. s = env_get("initrd_high");
  528. if (s) {
  529. /* a value of "no" or a similar string will act like 0,
  530. * turning the "load high" feature off. This is intentional.
  531. */
  532. initrd_high = hextoul(s, NULL);
  533. if (initrd_high == ~0)
  534. initrd_copy_to_ram = 0;
  535. } else {
  536. initrd_high = env_get_bootm_mapsize() + env_get_bootm_low();
  537. }
  538. debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
  539. initrd_high, initrd_copy_to_ram);
  540. if (rd_data) {
  541. if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
  542. debug(" in-place initrd\n");
  543. *initrd_start = rd_data;
  544. *initrd_end = rd_data + rd_len;
  545. lmb_reserve(lmb, rd_data, rd_len);
  546. } else {
  547. if (initrd_high)
  548. *initrd_start = (ulong)lmb_alloc_base(lmb,
  549. rd_len, 0x1000, initrd_high);
  550. else
  551. *initrd_start = (ulong)lmb_alloc(lmb, rd_len,
  552. 0x1000);
  553. if (*initrd_start == 0) {
  554. puts("ramdisk - allocation error\n");
  555. goto error;
  556. }
  557. bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
  558. *initrd_end = *initrd_start + rd_len;
  559. printf(" Loading Ramdisk to %08lx, end %08lx ... ",
  560. *initrd_start, *initrd_end);
  561. memmove_wd((void *)*initrd_start,
  562. (void *)rd_data, rd_len, CHUNKSZ);
  563. /*
  564. * Ensure the image is flushed to memory to handle
  565. * AMP boot scenarios in which we might not be
  566. * HW cache coherent
  567. */
  568. if (IS_ENABLED(CONFIG_MP)) {
  569. flush_cache((unsigned long)*initrd_start,
  570. ALIGN(rd_len, ARCH_DMA_MINALIGN));
  571. }
  572. puts("OK\n");
  573. }
  574. } else {
  575. *initrd_start = 0;
  576. *initrd_end = 0;
  577. }
  578. debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
  579. *initrd_start, *initrd_end);
  580. return 0;
  581. error:
  582. return -1;
  583. }
  584. int boot_get_setup(struct bootm_headers *images, u8 arch,
  585. ulong *setup_start, ulong *setup_len)
  586. {
  587. if (!CONFIG_IS_ENABLED(FIT))
  588. return -ENOENT;
  589. return boot_get_setup_fit(images, arch, setup_start, setup_len);
  590. }
  591. int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images,
  592. u8 arch, const ulong *ld_start, ulong * const ld_len)
  593. {
  594. ulong tmp_img_addr, img_data, img_len;
  595. void *buf;
  596. int conf_noffset;
  597. int fit_img_result;
  598. const char *uname, *name;
  599. int err;
  600. int devnum = 0; /* TODO support multi fpga platforms */
  601. if (!IS_ENABLED(CONFIG_FPGA))
  602. return -ENOSYS;
  603. /* Check to see if the images struct has a FIT configuration */
  604. if (!genimg_has_config(images)) {
  605. debug("## FIT configuration was not specified\n");
  606. return 0;
  607. }
  608. /*
  609. * Obtain the os FIT header from the images struct
  610. */
  611. tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
  612. buf = map_sysmem(tmp_img_addr, 0);
  613. /*
  614. * Check image type. For FIT images get FIT node
  615. * and attempt to locate a generic binary.
  616. */
  617. switch (genimg_get_format(buf)) {
  618. case IMAGE_FORMAT_FIT:
  619. conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
  620. uname = fdt_stringlist_get(buf, conf_noffset, FIT_FPGA_PROP, 0,
  621. NULL);
  622. if (!uname) {
  623. debug("## FPGA image is not specified\n");
  624. return 0;
  625. }
  626. fit_img_result = fit_image_load(images,
  627. tmp_img_addr,
  628. (const char **)&uname,
  629. &images->fit_uname_cfg,
  630. arch,
  631. IH_TYPE_FPGA,
  632. BOOTSTAGE_ID_FPGA_INIT,
  633. FIT_LOAD_OPTIONAL_NON_ZERO,
  634. &img_data, &img_len);
  635. debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n",
  636. uname, img_data, img_len);
  637. if (fit_img_result < 0) {
  638. /* Something went wrong! */
  639. return fit_img_result;
  640. }
  641. if (!fpga_is_partial_data(devnum, img_len)) {
  642. name = "full";
  643. err = fpga_loadbitstream(devnum, (char *)img_data,
  644. img_len, BIT_FULL);
  645. if (err)
  646. err = fpga_load(devnum, (const void *)img_data,
  647. img_len, BIT_FULL, 0);
  648. } else {
  649. name = "partial";
  650. err = fpga_loadbitstream(devnum, (char *)img_data,
  651. img_len, BIT_PARTIAL);
  652. if (err)
  653. err = fpga_load(devnum, (const void *)img_data,
  654. img_len, BIT_PARTIAL, 0);
  655. }
  656. if (err)
  657. return err;
  658. printf(" Programming %s bitstream... OK\n", name);
  659. break;
  660. default:
  661. printf("The given image format is not supported (corrupt?)\n");
  662. return 1;
  663. }
  664. return 0;
  665. }
  666. static void fit_loadable_process(u8 img_type,
  667. ulong img_data,
  668. ulong img_len)
  669. {
  670. int i;
  671. const unsigned int count =
  672. ll_entry_count(struct fit_loadable_tbl, fit_loadable);
  673. struct fit_loadable_tbl *fit_loadable_handler =
  674. ll_entry_start(struct fit_loadable_tbl, fit_loadable);
  675. /* For each loadable handler */
  676. for (i = 0; i < count; i++, fit_loadable_handler++)
  677. /* matching this type */
  678. if (fit_loadable_handler->type == img_type)
  679. /* call that handler with this image data */
  680. fit_loadable_handler->handler(img_data, img_len);
  681. }
  682. int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images,
  683. u8 arch, const ulong *ld_start, ulong * const ld_len)
  684. {
  685. /*
  686. * These variables are used to hold the current image location
  687. * in system memory.
  688. */
  689. ulong tmp_img_addr;
  690. /*
  691. * These two variables are requirements for fit_image_load, but
  692. * their values are not used
  693. */
  694. ulong img_data, img_len;
  695. void *buf;
  696. int loadables_index;
  697. int conf_noffset;
  698. int fit_img_result;
  699. const char *uname;
  700. u8 img_type;
  701. /* Check to see if the images struct has a FIT configuration */
  702. if (!genimg_has_config(images)) {
  703. debug("## FIT configuration was not specified\n");
  704. return 0;
  705. }
  706. /*
  707. * Obtain the os FIT header from the images struct
  708. */
  709. tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
  710. buf = map_sysmem(tmp_img_addr, 0);
  711. /*
  712. * Check image type. For FIT images get FIT node
  713. * and attempt to locate a generic binary.
  714. */
  715. switch (genimg_get_format(buf)) {
  716. case IMAGE_FORMAT_FIT:
  717. conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
  718. for (loadables_index = 0;
  719. uname = fdt_stringlist_get(buf, conf_noffset,
  720. FIT_LOADABLE_PROP,
  721. loadables_index, NULL), uname;
  722. loadables_index++) {
  723. fit_img_result = fit_image_load(images, tmp_img_addr,
  724. &uname,
  725. &images->fit_uname_cfg,
  726. arch, IH_TYPE_LOADABLE,
  727. BOOTSTAGE_ID_FIT_LOADABLE_START,
  728. FIT_LOAD_OPTIONAL_NON_ZERO,
  729. &img_data, &img_len);
  730. if (fit_img_result < 0) {
  731. /* Something went wrong! */
  732. return fit_img_result;
  733. }
  734. fit_img_result = fit_image_get_node(buf, uname);
  735. if (fit_img_result < 0) {
  736. /* Something went wrong! */
  737. return fit_img_result;
  738. }
  739. fit_img_result = fit_image_get_type(buf,
  740. fit_img_result,
  741. &img_type);
  742. if (fit_img_result < 0) {
  743. /* Something went wrong! */
  744. return fit_img_result;
  745. }
  746. fit_loadable_process(img_type, img_data, img_len);
  747. }
  748. break;
  749. default:
  750. printf("The given image format is not supported (corrupt?)\n");
  751. return 1;
  752. }
  753. return 0;
  754. }
  755. /**
  756. * boot_get_cmdline - allocate and initialize kernel cmdline
  757. * @lmb: pointer to lmb handle, will be used for memory mgmt
  758. * @cmd_start: pointer to a ulong variable, will hold cmdline start
  759. * @cmd_end: pointer to a ulong variable, will hold cmdline end
  760. *
  761. * This allocates space for kernel command line below
  762. * BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment
  763. * variable is present its contents is copied to allocated kernel
  764. * command line.
  765. *
  766. * returns:
  767. * 0 - success
  768. * -1 - failure
  769. */
  770. int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
  771. {
  772. int barg;
  773. char *cmdline;
  774. char *s;
  775. /*
  776. * Help the compiler detect that this function is only called when
  777. * CONFIG_SYS_BOOT_GET_CMDLINE is enabled
  778. */
  779. if (!IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE))
  780. return 0;
  781. barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE);
  782. cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf,
  783. env_get_bootm_mapsize() + env_get_bootm_low());
  784. if (!cmdline)
  785. return -1;
  786. s = env_get("bootargs");
  787. if (!s)
  788. s = "";
  789. strcpy(cmdline, s);
  790. *cmd_start = (ulong)cmdline;
  791. *cmd_end = *cmd_start + strlen(cmdline);
  792. debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
  793. return 0;
  794. }
  795. /**
  796. * boot_get_kbd - allocate and initialize kernel copy of board info
  797. * @lmb: pointer to lmb handle, will be used for memory mgmt
  798. * @kbd: double pointer to board info data
  799. *
  800. * boot_get_kbd() allocates space for kernel copy of board info data below
  801. * BOOTMAPSZ + env_get_bootm_low() address and kernel board info is initialized
  802. * with the current u-boot board info data.
  803. *
  804. * returns:
  805. * 0 - success
  806. * -1 - failure
  807. */
  808. int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd)
  809. {
  810. *kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb,
  811. sizeof(struct bd_info),
  812. 0xf,
  813. env_get_bootm_mapsize() +
  814. env_get_bootm_low());
  815. if (!*kbd)
  816. return -1;
  817. **kbd = *gd->bd;
  818. debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
  819. if (_DEBUG && IS_ENABLED(CONFIG_CMD_BDI))
  820. do_bdinfo(NULL, 0, 0, NULL);
  821. return 0;
  822. }
  823. int image_setup_linux(struct bootm_headers *images)
  824. {
  825. ulong of_size = images->ft_len;
  826. char **of_flat_tree = &images->ft_addr;
  827. struct lmb *lmb = images_lmb(images);
  828. int ret;
  829. /* This function cannot be called without lmb support */
  830. if (!IS_ENABLED(CONFIG_LMB))
  831. return -EFAULT;
  832. if (CONFIG_IS_ENABLED(OF_LIBFDT))
  833. boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
  834. if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
  835. ret = boot_get_cmdline(lmb, &images->cmdline_start,
  836. &images->cmdline_end);
  837. if (ret) {
  838. puts("ERROR with allocation of cmdline\n");
  839. return ret;
  840. }
  841. }
  842. if (CONFIG_IS_ENABLED(OF_LIBFDT)) {
  843. ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
  844. if (ret)
  845. return ret;
  846. }
  847. if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) {
  848. ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
  849. if (ret)
  850. return ret;
  851. }
  852. return 0;
  853. }
  854. void genimg_print_size(uint32_t size)
  855. {
  856. printf("%d Bytes = ", size);
  857. print_size(size, "\n");
  858. }
  859. void genimg_print_time(time_t timestamp)
  860. {
  861. struct rtc_time tm;
  862. rtc_to_tm(timestamp, &tm);
  863. printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n",
  864. tm.tm_year, tm.tm_mon, tm.tm_mday,
  865. tm.tm_hour, tm.tm_min, tm.tm_sec);
  866. }
  867. /**
  868. * get_default_image() - Return default property from /images
  869. *
  870. * Return: Pointer to value of default property (or NULL)
  871. */
  872. static const char *get_default_image(const void *fit)
  873. {
  874. int images_noffset;
  875. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  876. if (images_noffset < 0)
  877. return NULL;
  878. return fdt_getprop(fit, images_noffset, FIT_DEFAULT_PROP, NULL);
  879. }
  880. int image_locate_script(void *buf, int size, const char *fit_uname,
  881. const char *confname, char **datap, uint *lenp)
  882. {
  883. const struct legacy_img_hdr *hdr;
  884. const void *fit_data;
  885. const void *fit_hdr;
  886. size_t fit_len;
  887. int noffset;
  888. int verify;
  889. ulong len;
  890. u32 *data;
  891. verify = env_get_yesno("verify");
  892. switch (genimg_get_format(buf)) {
  893. case IMAGE_FORMAT_LEGACY:
  894. if (!IS_ENABLED(CONFIG_LEGACY_IMAGE_FORMAT)) {
  895. goto exit_image_format;
  896. } else {
  897. hdr = buf;
  898. if (!image_check_magic(hdr)) {
  899. puts("Bad magic number\n");
  900. return 1;
  901. }
  902. if (!image_check_hcrc(hdr)) {
  903. puts("Bad header crc\n");
  904. return 1;
  905. }
  906. if (verify) {
  907. if (!image_check_dcrc(hdr)) {
  908. puts("Bad data crc\n");
  909. return 1;
  910. }
  911. }
  912. if (!image_check_type(hdr, IH_TYPE_SCRIPT)) {
  913. puts("Bad image type\n");
  914. return 1;
  915. }
  916. /* get length of script */
  917. data = (u32 *)image_get_data(hdr);
  918. len = uimage_to_cpu(*data);
  919. if (!len) {
  920. puts("Empty Script\n");
  921. return 1;
  922. }
  923. /*
  924. * scripts are just multi-image files with one
  925. * component, so seek past the zero-terminated sequence
  926. * of image lengths to get to the actual image data
  927. */
  928. while (*data++);
  929. }
  930. break;
  931. case IMAGE_FORMAT_FIT:
  932. if (!IS_ENABLED(CONFIG_FIT)) {
  933. goto exit_image_format;
  934. } else {
  935. fit_hdr = buf;
  936. if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
  937. puts("Bad FIT image format\n");
  938. return 1;
  939. }
  940. if (!fit_uname) {
  941. /* If confname is empty, use the default */
  942. if (confname && *confname)
  943. noffset = fit_conf_get_node(fit_hdr, confname);
  944. else
  945. noffset = fit_conf_get_node(fit_hdr, NULL);
  946. if (noffset < 0) {
  947. if (!confname)
  948. goto fallback;
  949. printf("Could not find config %s\n", confname);
  950. return 1;
  951. }
  952. if (verify && fit_config_verify(fit_hdr, noffset))
  953. return 1;
  954. noffset = fit_conf_get_prop_node(fit_hdr,
  955. noffset,
  956. FIT_SCRIPT_PROP,
  957. IH_PHASE_NONE);
  958. if (noffset < 0) {
  959. if (!confname)
  960. goto fallback;
  961. printf("Could not find script in %s\n", confname);
  962. return 1;
  963. }
  964. } else {
  965. fallback:
  966. if (!fit_uname || !*fit_uname)
  967. fit_uname = get_default_image(fit_hdr);
  968. if (!fit_uname) {
  969. puts("No FIT subimage unit name\n");
  970. return 1;
  971. }
  972. /* get script component image node offset */
  973. noffset = fit_image_get_node(fit_hdr, fit_uname);
  974. if (noffset < 0) {
  975. printf("Can't find '%s' FIT subimage\n",
  976. fit_uname);
  977. return 1;
  978. }
  979. }
  980. if (!fit_image_check_type(fit_hdr, noffset,
  981. IH_TYPE_SCRIPT)) {
  982. puts("Not a image image\n");
  983. return 1;
  984. }
  985. /* verify integrity */
  986. if (verify && !fit_image_verify(fit_hdr, noffset)) {
  987. puts("Bad Data Hash\n");
  988. return 1;
  989. }
  990. /* get script subimage data address and length */
  991. if (fit_image_get_data_and_size(fit_hdr, noffset,
  992. &fit_data, &fit_len)) {
  993. puts("Could not find script subimage data\n");
  994. return 1;
  995. }
  996. data = (u32 *)fit_data;
  997. len = (ulong)fit_len;
  998. }
  999. break;
  1000. default:
  1001. goto exit_image_format;
  1002. }
  1003. *datap = (char *)data;
  1004. *lenp = len;
  1005. return 0;
  1006. exit_image_format:
  1007. puts("Wrong image format for \"source\" command\n");
  1008. return -EPERM;
  1009. }