image-fit.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492
  1. /*
  2. * Copyright (c) 2013, Google Inc.
  3. *
  4. * (C) Copyright 2008 Semihalf
  5. *
  6. * (C) Copyright 2000-2006
  7. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  8. *
  9. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. */
  27. #ifdef USE_HOSTCC
  28. #include "mkimage.h"
  29. #include <image.h>
  30. #include <time.h>
  31. #else
  32. #include <common.h>
  33. #endif /* !USE_HOSTCC*/
  34. #include <bootstage.h>
  35. #include <sha1.h>
  36. #include <u-boot/crc.h>
  37. #include <u-boot/md5.h>
  38. /*****************************************************************************/
  39. /* New uImage format routines */
  40. /*****************************************************************************/
  41. #ifndef USE_HOSTCC
  42. static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
  43. ulong *addr, const char **name)
  44. {
  45. const char *sep;
  46. *addr = addr_curr;
  47. *name = NULL;
  48. sep = strchr(spec, sepc);
  49. if (sep) {
  50. if (sep - spec > 0)
  51. *addr = simple_strtoul(spec, NULL, 16);
  52. *name = sep + 1;
  53. return 1;
  54. }
  55. return 0;
  56. }
  57. /**
  58. * fit_parse_conf - parse FIT configuration spec
  59. * @spec: input string, containing configuration spec
  60. * @add_curr: current image address (to be used as a possible default)
  61. * @addr: pointer to a ulong variable, will hold FIT image address of a given
  62. * configuration
  63. * @conf_name double pointer to a char, will hold pointer to a configuration
  64. * unit name
  65. *
  66. * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
  67. * where <addr> is a FIT image address that contains configuration
  68. * with a <conf> unit name.
  69. *
  70. * Address part is optional, and if omitted default add_curr will
  71. * be used instead.
  72. *
  73. * returns:
  74. * 1 if spec is a valid configuration string,
  75. * addr and conf_name are set accordingly
  76. * 0 otherwise
  77. */
  78. int fit_parse_conf(const char *spec, ulong addr_curr,
  79. ulong *addr, const char **conf_name)
  80. {
  81. return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
  82. }
  83. /**
  84. * fit_parse_subimage - parse FIT subimage spec
  85. * @spec: input string, containing subimage spec
  86. * @add_curr: current image address (to be used as a possible default)
  87. * @addr: pointer to a ulong variable, will hold FIT image address of a given
  88. * subimage
  89. * @image_name: double pointer to a char, will hold pointer to a subimage name
  90. *
  91. * fit_parse_subimage() expects subimage spec in the for of
  92. * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
  93. * subimage with a <subimg> unit name.
  94. *
  95. * Address part is optional, and if omitted default add_curr will
  96. * be used instead.
  97. *
  98. * returns:
  99. * 1 if spec is a valid subimage string,
  100. * addr and image_name are set accordingly
  101. * 0 otherwise
  102. */
  103. int fit_parse_subimage(const char *spec, ulong addr_curr,
  104. ulong *addr, const char **image_name)
  105. {
  106. return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
  107. }
  108. #endif /* !USE_HOSTCC */
  109. static void fit_get_debug(const void *fit, int noffset,
  110. char *prop_name, int err)
  111. {
  112. debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
  113. prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
  114. fdt_strerror(err));
  115. }
  116. #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
  117. /**
  118. * fit_print_contents - prints out the contents of the FIT format image
  119. * @fit: pointer to the FIT format image header
  120. * @p: pointer to prefix string
  121. *
  122. * fit_print_contents() formats a multi line FIT image contents description.
  123. * The routine prints out FIT image properties (root node level) follwed by
  124. * the details of each component image.
  125. *
  126. * returns:
  127. * no returned results
  128. */
  129. void fit_print_contents(const void *fit)
  130. {
  131. char *desc;
  132. char *uname;
  133. int images_noffset;
  134. int confs_noffset;
  135. int noffset;
  136. int ndepth;
  137. int count = 0;
  138. int ret;
  139. const char *p;
  140. time_t timestamp;
  141. /* Indent string is defined in header image.h */
  142. p = IMAGE_INDENT_STRING;
  143. /* Root node properties */
  144. ret = fit_get_desc(fit, 0, &desc);
  145. printf("%sFIT description: ", p);
  146. if (ret)
  147. printf("unavailable\n");
  148. else
  149. printf("%s\n", desc);
  150. if (IMAGE_ENABLE_TIMESTAMP) {
  151. ret = fit_get_timestamp(fit, 0, &timestamp);
  152. printf("%sCreated: ", p);
  153. if (ret)
  154. printf("unavailable\n");
  155. else
  156. genimg_print_time(timestamp);
  157. }
  158. /* Find images parent node offset */
  159. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  160. if (images_noffset < 0) {
  161. printf("Can't find images parent node '%s' (%s)\n",
  162. FIT_IMAGES_PATH, fdt_strerror(images_noffset));
  163. return;
  164. }
  165. /* Process its subnodes, print out component images details */
  166. for (ndepth = 0, count = 0,
  167. noffset = fdt_next_node(fit, images_noffset, &ndepth);
  168. (noffset >= 0) && (ndepth > 0);
  169. noffset = fdt_next_node(fit, noffset, &ndepth)) {
  170. if (ndepth == 1) {
  171. /*
  172. * Direct child node of the images parent node,
  173. * i.e. component image node.
  174. */
  175. printf("%s Image %u (%s)\n", p, count++,
  176. fit_get_name(fit, noffset, NULL));
  177. fit_image_print(fit, noffset, p);
  178. }
  179. }
  180. /* Find configurations parent node offset */
  181. confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
  182. if (confs_noffset < 0) {
  183. debug("Can't get configurations parent node '%s' (%s)\n",
  184. FIT_CONFS_PATH, fdt_strerror(confs_noffset));
  185. return;
  186. }
  187. /* get default configuration unit name from default property */
  188. uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
  189. if (uname)
  190. printf("%s Default Configuration: '%s'\n", p, uname);
  191. /* Process its subnodes, print out configurations details */
  192. for (ndepth = 0, count = 0,
  193. noffset = fdt_next_node(fit, confs_noffset, &ndepth);
  194. (noffset >= 0) && (ndepth > 0);
  195. noffset = fdt_next_node(fit, noffset, &ndepth)) {
  196. if (ndepth == 1) {
  197. /*
  198. * Direct child node of the configurations parent node,
  199. * i.e. configuration node.
  200. */
  201. printf("%s Configuration %u (%s)\n", p, count++,
  202. fit_get_name(fit, noffset, NULL));
  203. fit_conf_print(fit, noffset, p);
  204. }
  205. }
  206. }
  207. /**
  208. * fit_image_print_data() - prints out the hash node details
  209. * @fit: pointer to the FIT format image header
  210. * @noffset: offset of the hash node
  211. * @p: pointer to prefix string
  212. *
  213. * fit_image_print_data() lists properies for the processed hash node
  214. *
  215. * returns:
  216. * no returned results
  217. */
  218. static void fit_image_print_data(const void *fit, int noffset, const char *p)
  219. {
  220. char *algo;
  221. uint8_t *value;
  222. int value_len;
  223. int i, ret;
  224. /*
  225. * Check subnode name, must be equal to "hash".
  226. * Multiple hash nodes require unique unit node
  227. * names, e.g. hash@1, hash@2, etc.
  228. */
  229. if (strncmp(fit_get_name(fit, noffset, NULL),
  230. FIT_HASH_NODENAME,
  231. strlen(FIT_HASH_NODENAME)) != 0)
  232. return;
  233. debug("%s Hash node: '%s'\n", p,
  234. fit_get_name(fit, noffset, NULL));
  235. printf("%s Hash algo: ", p);
  236. if (fit_image_hash_get_algo(fit, noffset, &algo)) {
  237. printf("invalid/unsupported\n");
  238. return;
  239. }
  240. printf("%s\n", algo);
  241. ret = fit_image_hash_get_value(fit, noffset, &value,
  242. &value_len);
  243. printf("%s Hash value: ", p);
  244. if (ret) {
  245. printf("unavailable\n");
  246. } else {
  247. for (i = 0; i < value_len; i++)
  248. printf("%02x", value[i]);
  249. printf("\n");
  250. }
  251. debug("%s Hash len: %d\n", p, value_len);
  252. }
  253. /**
  254. * fit_image_print_verification_data() - prints out the hash/signature details
  255. * @fit: pointer to the FIT format image header
  256. * @noffset: offset of the hash or signature node
  257. * @p: pointer to prefix string
  258. *
  259. * This lists properies for the processed hash node
  260. *
  261. * returns:
  262. * no returned results
  263. */
  264. static void fit_image_print_verification_data(const void *fit, int noffset,
  265. const char *p)
  266. {
  267. const char *name;
  268. /*
  269. * Check subnode name, must be equal to "hash" or "signature".
  270. * Multiple hash/signature nodes require unique unit node
  271. * names, e.g. hash@1, hash@2, signature@1, signature@2, etc.
  272. */
  273. name = fit_get_name(fit, noffset, NULL);
  274. if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME)))
  275. fit_image_print_data(fit, noffset, p);
  276. }
  277. /**
  278. * fit_image_print - prints out the FIT component image details
  279. * @fit: pointer to the FIT format image header
  280. * @image_noffset: offset of the component image node
  281. * @p: pointer to prefix string
  282. *
  283. * fit_image_print() lists all mandatory properies for the processed component
  284. * image. If present, hash nodes are printed out as well. Load
  285. * address for images of type firmware is also printed out. Since the load
  286. * address is not mandatory for firmware images, it will be output as
  287. * "unavailable" when not present.
  288. *
  289. * returns:
  290. * no returned results
  291. */
  292. void fit_image_print(const void *fit, int image_noffset, const char *p)
  293. {
  294. char *desc;
  295. uint8_t type, arch, os, comp;
  296. size_t size;
  297. ulong load, entry;
  298. const void *data;
  299. int noffset;
  300. int ndepth;
  301. int ret;
  302. /* Mandatory properties */
  303. ret = fit_get_desc(fit, image_noffset, &desc);
  304. printf("%s Description: ", p);
  305. if (ret)
  306. printf("unavailable\n");
  307. else
  308. printf("%s\n", desc);
  309. fit_image_get_type(fit, image_noffset, &type);
  310. printf("%s Type: %s\n", p, genimg_get_type_name(type));
  311. fit_image_get_comp(fit, image_noffset, &comp);
  312. printf("%s Compression: %s\n", p, genimg_get_comp_name(comp));
  313. ret = fit_image_get_data(fit, image_noffset, &data, &size);
  314. #ifndef USE_HOSTCC
  315. printf("%s Data Start: ", p);
  316. if (ret)
  317. printf("unavailable\n");
  318. else
  319. printf("0x%08lx\n", (ulong)data);
  320. #endif
  321. printf("%s Data Size: ", p);
  322. if (ret)
  323. printf("unavailable\n");
  324. else
  325. genimg_print_size(size);
  326. /* Remaining, type dependent properties */
  327. if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
  328. (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
  329. (type == IH_TYPE_FLATDT)) {
  330. fit_image_get_arch(fit, image_noffset, &arch);
  331. printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch));
  332. }
  333. if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) {
  334. fit_image_get_os(fit, image_noffset, &os);
  335. printf("%s OS: %s\n", p, genimg_get_os_name(os));
  336. }
  337. if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
  338. (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) {
  339. ret = fit_image_get_load(fit, image_noffset, &load);
  340. printf("%s Load Address: ", p);
  341. if (ret)
  342. printf("unavailable\n");
  343. else
  344. printf("0x%08lx\n", load);
  345. }
  346. if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
  347. (type == IH_TYPE_RAMDISK)) {
  348. fit_image_get_entry(fit, image_noffset, &entry);
  349. printf("%s Entry Point: ", p);
  350. if (ret)
  351. printf("unavailable\n");
  352. else
  353. printf("0x%08lx\n", entry);
  354. }
  355. /* Process all hash subnodes of the component image node */
  356. for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
  357. (noffset >= 0) && (ndepth > 0);
  358. noffset = fdt_next_node(fit, noffset, &ndepth)) {
  359. if (ndepth == 1) {
  360. /* Direct child node of the component image node */
  361. fit_image_print_verification_data(fit, noffset, p);
  362. }
  363. }
  364. }
  365. #endif
  366. /**
  367. * fit_get_desc - get node description property
  368. * @fit: pointer to the FIT format image header
  369. * @noffset: node offset
  370. * @desc: double pointer to the char, will hold pointer to the descrption
  371. *
  372. * fit_get_desc() reads description property from a given node, if
  373. * description is found pointer to it is returened in third call argument.
  374. *
  375. * returns:
  376. * 0, on success
  377. * -1, on failure
  378. */
  379. int fit_get_desc(const void *fit, int noffset, char **desc)
  380. {
  381. int len;
  382. *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
  383. if (*desc == NULL) {
  384. fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
  385. return -1;
  386. }
  387. return 0;
  388. }
  389. /**
  390. * fit_get_timestamp - get node timestamp property
  391. * @fit: pointer to the FIT format image header
  392. * @noffset: node offset
  393. * @timestamp: pointer to the time_t, will hold read timestamp
  394. *
  395. * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
  396. * is found and has a correct size its value is retured in third call
  397. * argument.
  398. *
  399. * returns:
  400. * 0, on success
  401. * -1, on property read failure
  402. * -2, on wrong timestamp size
  403. */
  404. int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
  405. {
  406. int len;
  407. const void *data;
  408. data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
  409. if (data == NULL) {
  410. fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
  411. return -1;
  412. }
  413. if (len != sizeof(uint32_t)) {
  414. debug("FIT timestamp with incorrect size of (%u)\n", len);
  415. return -2;
  416. }
  417. *timestamp = uimage_to_cpu(*((uint32_t *)data));
  418. return 0;
  419. }
  420. /**
  421. * fit_image_get_node - get node offset for component image of a given unit name
  422. * @fit: pointer to the FIT format image header
  423. * @image_uname: component image node unit name
  424. *
  425. * fit_image_get_node() finds a component image (withing the '/images'
  426. * node) of a provided unit name. If image is found its node offset is
  427. * returned to the caller.
  428. *
  429. * returns:
  430. * image node offset when found (>=0)
  431. * negative number on failure (FDT_ERR_* code)
  432. */
  433. int fit_image_get_node(const void *fit, const char *image_uname)
  434. {
  435. int noffset, images_noffset;
  436. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  437. if (images_noffset < 0) {
  438. debug("Can't find images parent node '%s' (%s)\n",
  439. FIT_IMAGES_PATH, fdt_strerror(images_noffset));
  440. return images_noffset;
  441. }
  442. noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
  443. if (noffset < 0) {
  444. debug("Can't get node offset for image unit name: '%s' (%s)\n",
  445. image_uname, fdt_strerror(noffset));
  446. }
  447. return noffset;
  448. }
  449. /**
  450. * fit_image_get_os - get os id for a given component image node
  451. * @fit: pointer to the FIT format image header
  452. * @noffset: component image node offset
  453. * @os: pointer to the uint8_t, will hold os numeric id
  454. *
  455. * fit_image_get_os() finds os property in a given component image node.
  456. * If the property is found, its (string) value is translated to the numeric
  457. * id which is returned to the caller.
  458. *
  459. * returns:
  460. * 0, on success
  461. * -1, on failure
  462. */
  463. int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
  464. {
  465. int len;
  466. const void *data;
  467. /* Get OS name from property data */
  468. data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
  469. if (data == NULL) {
  470. fit_get_debug(fit, noffset, FIT_OS_PROP, len);
  471. *os = -1;
  472. return -1;
  473. }
  474. /* Translate OS name to id */
  475. *os = genimg_get_os_id(data);
  476. return 0;
  477. }
  478. /**
  479. * fit_image_get_arch - get arch id for a given component image node
  480. * @fit: pointer to the FIT format image header
  481. * @noffset: component image node offset
  482. * @arch: pointer to the uint8_t, will hold arch numeric id
  483. *
  484. * fit_image_get_arch() finds arch property in a given component image node.
  485. * If the property is found, its (string) value is translated to the numeric
  486. * id which is returned to the caller.
  487. *
  488. * returns:
  489. * 0, on success
  490. * -1, on failure
  491. */
  492. int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
  493. {
  494. int len;
  495. const void *data;
  496. /* Get architecture name from property data */
  497. data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
  498. if (data == NULL) {
  499. fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
  500. *arch = -1;
  501. return -1;
  502. }
  503. /* Translate architecture name to id */
  504. *arch = genimg_get_arch_id(data);
  505. return 0;
  506. }
  507. /**
  508. * fit_image_get_type - get type id for a given component image node
  509. * @fit: pointer to the FIT format image header
  510. * @noffset: component image node offset
  511. * @type: pointer to the uint8_t, will hold type numeric id
  512. *
  513. * fit_image_get_type() finds type property in a given component image node.
  514. * If the property is found, its (string) value is translated to the numeric
  515. * id which is returned to the caller.
  516. *
  517. * returns:
  518. * 0, on success
  519. * -1, on failure
  520. */
  521. int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
  522. {
  523. int len;
  524. const void *data;
  525. /* Get image type name from property data */
  526. data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
  527. if (data == NULL) {
  528. fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
  529. *type = -1;
  530. return -1;
  531. }
  532. /* Translate image type name to id */
  533. *type = genimg_get_type_id(data);
  534. return 0;
  535. }
  536. /**
  537. * fit_image_get_comp - get comp id for a given component image node
  538. * @fit: pointer to the FIT format image header
  539. * @noffset: component image node offset
  540. * @comp: pointer to the uint8_t, will hold comp numeric id
  541. *
  542. * fit_image_get_comp() finds comp property in a given component image node.
  543. * If the property is found, its (string) value is translated to the numeric
  544. * id which is returned to the caller.
  545. *
  546. * returns:
  547. * 0, on success
  548. * -1, on failure
  549. */
  550. int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
  551. {
  552. int len;
  553. const void *data;
  554. /* Get compression name from property data */
  555. data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
  556. if (data == NULL) {
  557. fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
  558. *comp = -1;
  559. return -1;
  560. }
  561. /* Translate compression name to id */
  562. *comp = genimg_get_comp_id(data);
  563. return 0;
  564. }
  565. /**
  566. * fit_image_get_load() - get load addr property for given component image node
  567. * @fit: pointer to the FIT format image header
  568. * @noffset: component image node offset
  569. * @load: pointer to the uint32_t, will hold load address
  570. *
  571. * fit_image_get_load() finds load address property in a given component
  572. * image node. If the property is found, its value is returned to the caller.
  573. *
  574. * returns:
  575. * 0, on success
  576. * -1, on failure
  577. */
  578. int fit_image_get_load(const void *fit, int noffset, ulong *load)
  579. {
  580. int len;
  581. const uint32_t *data;
  582. data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len);
  583. if (data == NULL) {
  584. fit_get_debug(fit, noffset, FIT_LOAD_PROP, len);
  585. return -1;
  586. }
  587. *load = uimage_to_cpu(*data);
  588. return 0;
  589. }
  590. /**
  591. * fit_image_get_entry() - get entry point address property
  592. * @fit: pointer to the FIT format image header
  593. * @noffset: component image node offset
  594. * @entry: pointer to the uint32_t, will hold entry point address
  595. *
  596. * This gets the entry point address property for a given component image
  597. * node.
  598. *
  599. * fit_image_get_entry() finds entry point address property in a given
  600. * component image node. If the property is found, its value is returned
  601. * to the caller.
  602. *
  603. * returns:
  604. * 0, on success
  605. * -1, on failure
  606. */
  607. int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
  608. {
  609. int len;
  610. const uint32_t *data;
  611. data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len);
  612. if (data == NULL) {
  613. fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len);
  614. return -1;
  615. }
  616. *entry = uimage_to_cpu(*data);
  617. return 0;
  618. }
  619. /**
  620. * fit_image_get_data - get data property and its size for a given component image node
  621. * @fit: pointer to the FIT format image header
  622. * @noffset: component image node offset
  623. * @data: double pointer to void, will hold data property's data address
  624. * @size: pointer to size_t, will hold data property's data size
  625. *
  626. * fit_image_get_data() finds data property in a given component image node.
  627. * If the property is found its data start address and size are returned to
  628. * the caller.
  629. *
  630. * returns:
  631. * 0, on success
  632. * -1, on failure
  633. */
  634. int fit_image_get_data(const void *fit, int noffset,
  635. const void **data, size_t *size)
  636. {
  637. int len;
  638. *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
  639. if (*data == NULL) {
  640. fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
  641. *size = 0;
  642. return -1;
  643. }
  644. *size = len;
  645. return 0;
  646. }
  647. /**
  648. * fit_image_hash_get_algo - get hash algorithm name
  649. * @fit: pointer to the FIT format image header
  650. * @noffset: hash node offset
  651. * @algo: double pointer to char, will hold pointer to the algorithm name
  652. *
  653. * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
  654. * If the property is found its data start address is returned to the caller.
  655. *
  656. * returns:
  657. * 0, on success
  658. * -1, on failure
  659. */
  660. int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
  661. {
  662. int len;
  663. *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
  664. if (*algo == NULL) {
  665. fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
  666. return -1;
  667. }
  668. return 0;
  669. }
  670. /**
  671. * fit_image_hash_get_value - get hash value and length
  672. * @fit: pointer to the FIT format image header
  673. * @noffset: hash node offset
  674. * @value: double pointer to uint8_t, will hold address of a hash value data
  675. * @value_len: pointer to an int, will hold hash data length
  676. *
  677. * fit_image_hash_get_value() finds hash value property in a given hash node.
  678. * If the property is found its data start address and size are returned to
  679. * the caller.
  680. *
  681. * returns:
  682. * 0, on success
  683. * -1, on failure
  684. */
  685. int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
  686. int *value_len)
  687. {
  688. int len;
  689. *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
  690. if (*value == NULL) {
  691. fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
  692. *value_len = 0;
  693. return -1;
  694. }
  695. *value_len = len;
  696. return 0;
  697. }
  698. /**
  699. * fit_image_hash_get_ignore - get hash ignore flag
  700. * @fit: pointer to the FIT format image header
  701. * @noffset: hash node offset
  702. * @ignore: pointer to an int, will hold hash ignore flag
  703. *
  704. * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
  705. * If the property is found and non-zero, the hash algorithm is not verified by
  706. * u-boot automatically.
  707. *
  708. * returns:
  709. * 0, on ignore not found
  710. * value, on ignore found
  711. */
  712. static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
  713. {
  714. int len;
  715. int *value;
  716. value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
  717. if (value == NULL || len != sizeof(int))
  718. *ignore = 0;
  719. else
  720. *ignore = *value;
  721. return 0;
  722. }
  723. /**
  724. * fit_set_timestamp - set node timestamp property
  725. * @fit: pointer to the FIT format image header
  726. * @noffset: node offset
  727. * @timestamp: timestamp value to be set
  728. *
  729. * fit_set_timestamp() attempts to set timestamp property in the requested
  730. * node and returns operation status to the caller.
  731. *
  732. * returns:
  733. * 0, on success
  734. * -1, on property read failure
  735. */
  736. int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
  737. {
  738. uint32_t t;
  739. int ret;
  740. t = cpu_to_uimage(timestamp);
  741. ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
  742. sizeof(uint32_t));
  743. if (ret) {
  744. printf("Can't set '%s' property for '%s' node (%s)\n",
  745. FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
  746. fdt_strerror(ret));
  747. return -1;
  748. }
  749. return 0;
  750. }
  751. /**
  752. * calculate_hash - calculate and return hash for provided input data
  753. * @data: pointer to the input data
  754. * @data_len: data length
  755. * @algo: requested hash algorithm
  756. * @value: pointer to the char, will hold hash value data (caller must
  757. * allocate enough free space)
  758. * value_len: length of the calculated hash
  759. *
  760. * calculate_hash() computes input data hash according to the requested
  761. * algorithm.
  762. * Resulting hash value is placed in caller provided 'value' buffer, length
  763. * of the calculated hash is returned via value_len pointer argument.
  764. *
  765. * returns:
  766. * 0, on success
  767. * -1, when algo is unsupported
  768. */
  769. int calculate_hash(const void *data, int data_len, const char *algo,
  770. uint8_t *value, int *value_len)
  771. {
  772. if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
  773. *((uint32_t *)value) = crc32_wd(0, data, data_len,
  774. CHUNKSZ_CRC32);
  775. *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
  776. *value_len = 4;
  777. } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
  778. sha1_csum_wd((unsigned char *)data, data_len,
  779. (unsigned char *)value, CHUNKSZ_SHA1);
  780. *value_len = 20;
  781. } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
  782. md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
  783. *value_len = 16;
  784. } else {
  785. debug("Unsupported hash alogrithm\n");
  786. return -1;
  787. }
  788. return 0;
  789. }
  790. static int fit_image_check_hash(const void *fit, int noffset, const void *data,
  791. size_t size, char **err_msgp)
  792. {
  793. uint8_t value[FIT_MAX_HASH_LEN];
  794. int value_len;
  795. char *algo;
  796. uint8_t *fit_value;
  797. int fit_value_len;
  798. int ignore;
  799. *err_msgp = NULL;
  800. if (fit_image_hash_get_algo(fit, noffset, &algo)) {
  801. *err_msgp = "Can't get hash algo property";
  802. return -1;
  803. }
  804. printf("%s", algo);
  805. if (IMAGE_ENABLE_IGNORE) {
  806. fit_image_hash_get_ignore(fit, noffset, &ignore);
  807. if (ignore) {
  808. printf("-skipped ");
  809. return 0;
  810. }
  811. }
  812. if (fit_image_hash_get_value(fit, noffset, &fit_value,
  813. &fit_value_len)) {
  814. *err_msgp = "Can't get hash value property";
  815. return -1;
  816. }
  817. if (calculate_hash(data, size, algo, value, &value_len)) {
  818. *err_msgp = "Unsupported hash algorithm";
  819. return -1;
  820. }
  821. if (value_len != fit_value_len) {
  822. *err_msgp = "Bad hash value len";
  823. return -1;
  824. } else if (memcmp(value, fit_value, value_len) != 0) {
  825. *err_msgp = "Bad hash value";
  826. return -1;
  827. }
  828. return 0;
  829. }
  830. /**
  831. * fit_image_verify - verify data intergity
  832. * @fit: pointer to the FIT format image header
  833. * @image_noffset: component image node offset
  834. *
  835. * fit_image_verify() goes over component image hash nodes,
  836. * re-calculates each data hash and compares with the value stored in hash
  837. * node.
  838. *
  839. * returns:
  840. * 1, if all hashes are valid
  841. * 0, otherwise (or on error)
  842. */
  843. int fit_image_verify(const void *fit, int image_noffset)
  844. {
  845. const void *data;
  846. size_t size;
  847. int noffset;
  848. char *err_msg = "";
  849. /* Get image data and data length */
  850. if (fit_image_get_data(fit, image_noffset, &data, &size)) {
  851. err_msg = "Can't get image data/size";
  852. return 0;
  853. }
  854. /* Process all hash subnodes of the component image node */
  855. for (noffset = fdt_first_subnode(fit, image_noffset);
  856. noffset >= 0;
  857. noffset = fdt_next_subnode(fit, noffset)) {
  858. const char *name = fit_get_name(fit, noffset, NULL);
  859. /*
  860. * Check subnode name, must be equal to "hash".
  861. * Multiple hash nodes require unique unit node
  862. * names, e.g. hash@1, hash@2, etc.
  863. */
  864. if (!strncmp(name, FIT_HASH_NODENAME,
  865. strlen(FIT_HASH_NODENAME))) {
  866. if (fit_image_check_hash(fit, noffset, data, size,
  867. &err_msg))
  868. goto error;
  869. puts("+ ");
  870. }
  871. }
  872. if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
  873. err_msg = "Corrupted or truncated tree";
  874. goto error;
  875. }
  876. return 1;
  877. error:
  878. printf(" error!\n%s for '%s' hash node in '%s' image node\n",
  879. err_msg, fit_get_name(fit, noffset, NULL),
  880. fit_get_name(fit, image_noffset, NULL));
  881. return 0;
  882. }
  883. /**
  884. * fit_all_image_verify - verify data intergity for all images
  885. * @fit: pointer to the FIT format image header
  886. *
  887. * fit_all_image_verify() goes over all images in the FIT and
  888. * for every images checks if all it's hashes are valid.
  889. *
  890. * returns:
  891. * 1, if all hashes of all images are valid
  892. * 0, otherwise (or on error)
  893. */
  894. int fit_all_image_verify(const void *fit)
  895. {
  896. int images_noffset;
  897. int noffset;
  898. int ndepth;
  899. int count;
  900. /* Find images parent node offset */
  901. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  902. if (images_noffset < 0) {
  903. printf("Can't find images parent node '%s' (%s)\n",
  904. FIT_IMAGES_PATH, fdt_strerror(images_noffset));
  905. return 0;
  906. }
  907. /* Process all image subnodes, check hashes for each */
  908. printf("## Checking hash(es) for FIT Image at %08lx ...\n",
  909. (ulong)fit);
  910. for (ndepth = 0, count = 0,
  911. noffset = fdt_next_node(fit, images_noffset, &ndepth);
  912. (noffset >= 0) && (ndepth > 0);
  913. noffset = fdt_next_node(fit, noffset, &ndepth)) {
  914. if (ndepth == 1) {
  915. /*
  916. * Direct child node of the images parent node,
  917. * i.e. component image node.
  918. */
  919. printf(" Hash(es) for Image %u (%s): ", count++,
  920. fit_get_name(fit, noffset, NULL));
  921. if (!fit_image_verify(fit, noffset))
  922. return 0;
  923. printf("\n");
  924. }
  925. }
  926. return 1;
  927. }
  928. /**
  929. * fit_image_check_os - check whether image node is of a given os type
  930. * @fit: pointer to the FIT format image header
  931. * @noffset: component image node offset
  932. * @os: requested image os
  933. *
  934. * fit_image_check_os() reads image os property and compares its numeric
  935. * id with the requested os. Comparison result is returned to the caller.
  936. *
  937. * returns:
  938. * 1 if image is of given os type
  939. * 0 otherwise (or on error)
  940. */
  941. int fit_image_check_os(const void *fit, int noffset, uint8_t os)
  942. {
  943. uint8_t image_os;
  944. if (fit_image_get_os(fit, noffset, &image_os))
  945. return 0;
  946. return (os == image_os);
  947. }
  948. /**
  949. * fit_image_check_arch - check whether image node is of a given arch
  950. * @fit: pointer to the FIT format image header
  951. * @noffset: component image node offset
  952. * @arch: requested imagearch
  953. *
  954. * fit_image_check_arch() reads image arch property and compares its numeric
  955. * id with the requested arch. Comparison result is returned to the caller.
  956. *
  957. * returns:
  958. * 1 if image is of given arch
  959. * 0 otherwise (or on error)
  960. */
  961. int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
  962. {
  963. uint8_t image_arch;
  964. if (fit_image_get_arch(fit, noffset, &image_arch))
  965. return 0;
  966. return (arch == image_arch);
  967. }
  968. /**
  969. * fit_image_check_type - check whether image node is of a given type
  970. * @fit: pointer to the FIT format image header
  971. * @noffset: component image node offset
  972. * @type: requested image type
  973. *
  974. * fit_image_check_type() reads image type property and compares its numeric
  975. * id with the requested type. Comparison result is returned to the caller.
  976. *
  977. * returns:
  978. * 1 if image is of given type
  979. * 0 otherwise (or on error)
  980. */
  981. int fit_image_check_type(const void *fit, int noffset, uint8_t type)
  982. {
  983. uint8_t image_type;
  984. if (fit_image_get_type(fit, noffset, &image_type))
  985. return 0;
  986. return (type == image_type);
  987. }
  988. /**
  989. * fit_image_check_comp - check whether image node uses given compression
  990. * @fit: pointer to the FIT format image header
  991. * @noffset: component image node offset
  992. * @comp: requested image compression type
  993. *
  994. * fit_image_check_comp() reads image compression property and compares its
  995. * numeric id with the requested compression type. Comparison result is
  996. * returned to the caller.
  997. *
  998. * returns:
  999. * 1 if image uses requested compression
  1000. * 0 otherwise (or on error)
  1001. */
  1002. int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
  1003. {
  1004. uint8_t image_comp;
  1005. if (fit_image_get_comp(fit, noffset, &image_comp))
  1006. return 0;
  1007. return (comp == image_comp);
  1008. }
  1009. /**
  1010. * fit_check_format - sanity check FIT image format
  1011. * @fit: pointer to the FIT format image header
  1012. *
  1013. * fit_check_format() runs a basic sanity FIT image verification.
  1014. * Routine checks for mandatory properties, nodes, etc.
  1015. *
  1016. * returns:
  1017. * 1, on success
  1018. * 0, on failure
  1019. */
  1020. int fit_check_format(const void *fit)
  1021. {
  1022. /* mandatory / node 'description' property */
  1023. if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
  1024. debug("Wrong FIT format: no description\n");
  1025. return 0;
  1026. }
  1027. if (IMAGE_ENABLE_TIMESTAMP) {
  1028. /* mandatory / node 'timestamp' property */
  1029. if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
  1030. debug("Wrong FIT format: no timestamp\n");
  1031. return 0;
  1032. }
  1033. }
  1034. /* mandatory subimages parent '/images' node */
  1035. if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
  1036. debug("Wrong FIT format: no images parent node\n");
  1037. return 0;
  1038. }
  1039. return 1;
  1040. }
  1041. /**
  1042. * fit_conf_find_compat
  1043. * @fit: pointer to the FIT format image header
  1044. * @fdt: pointer to the device tree to compare against
  1045. *
  1046. * fit_conf_find_compat() attempts to find the configuration whose fdt is the
  1047. * most compatible with the passed in device tree.
  1048. *
  1049. * Example:
  1050. *
  1051. * / o image-tree
  1052. * |-o images
  1053. * | |-o fdt@1
  1054. * | |-o fdt@2
  1055. * |
  1056. * |-o configurations
  1057. * |-o config@1
  1058. * | |-fdt = fdt@1
  1059. * |
  1060. * |-o config@2
  1061. * |-fdt = fdt@2
  1062. *
  1063. * / o U-Boot fdt
  1064. * |-compatible = "foo,bar", "bim,bam"
  1065. *
  1066. * / o kernel fdt1
  1067. * |-compatible = "foo,bar",
  1068. *
  1069. * / o kernel fdt2
  1070. * |-compatible = "bim,bam", "baz,biz"
  1071. *
  1072. * Configuration 1 would be picked because the first string in U-Boot's
  1073. * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
  1074. * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
  1075. *
  1076. * returns:
  1077. * offset to the configuration to use if one was found
  1078. * -1 otherwise
  1079. */
  1080. int fit_conf_find_compat(const void *fit, const void *fdt)
  1081. {
  1082. int ndepth = 0;
  1083. int noffset, confs_noffset, images_noffset;
  1084. const void *fdt_compat;
  1085. int fdt_compat_len;
  1086. int best_match_offset = 0;
  1087. int best_match_pos = 0;
  1088. confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
  1089. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  1090. if (confs_noffset < 0 || images_noffset < 0) {
  1091. debug("Can't find configurations or images nodes.\n");
  1092. return -1;
  1093. }
  1094. fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
  1095. if (!fdt_compat) {
  1096. debug("Fdt for comparison has no \"compatible\" property.\n");
  1097. return -1;
  1098. }
  1099. /*
  1100. * Loop over the configurations in the FIT image.
  1101. */
  1102. for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
  1103. (noffset >= 0) && (ndepth > 0);
  1104. noffset = fdt_next_node(fit, noffset, &ndepth)) {
  1105. const void *kfdt;
  1106. const char *kfdt_name;
  1107. int kfdt_noffset;
  1108. const char *cur_fdt_compat;
  1109. int len;
  1110. size_t size;
  1111. int i;
  1112. if (ndepth > 1)
  1113. continue;
  1114. kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
  1115. if (!kfdt_name) {
  1116. debug("No fdt property found.\n");
  1117. continue;
  1118. }
  1119. kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
  1120. kfdt_name);
  1121. if (kfdt_noffset < 0) {
  1122. debug("No image node named \"%s\" found.\n",
  1123. kfdt_name);
  1124. continue;
  1125. }
  1126. /*
  1127. * Get a pointer to this configuration's fdt.
  1128. */
  1129. if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
  1130. debug("Failed to get fdt \"%s\".\n", kfdt_name);
  1131. continue;
  1132. }
  1133. len = fdt_compat_len;
  1134. cur_fdt_compat = fdt_compat;
  1135. /*
  1136. * Look for a match for each U-Boot compatibility string in
  1137. * turn in this configuration's fdt.
  1138. */
  1139. for (i = 0; len > 0 &&
  1140. (!best_match_offset || best_match_pos > i); i++) {
  1141. int cur_len = strlen(cur_fdt_compat) + 1;
  1142. if (!fdt_node_check_compatible(kfdt, 0,
  1143. cur_fdt_compat)) {
  1144. best_match_offset = noffset;
  1145. best_match_pos = i;
  1146. break;
  1147. }
  1148. len -= cur_len;
  1149. cur_fdt_compat += cur_len;
  1150. }
  1151. }
  1152. if (!best_match_offset) {
  1153. debug("No match found.\n");
  1154. return -1;
  1155. }
  1156. return best_match_offset;
  1157. }
  1158. /**
  1159. * fit_conf_get_node - get node offset for configuration of a given unit name
  1160. * @fit: pointer to the FIT format image header
  1161. * @conf_uname: configuration node unit name
  1162. *
  1163. * fit_conf_get_node() finds a configuration (withing the '/configurations'
  1164. * parant node) of a provided unit name. If configuration is found its node
  1165. * offset is returned to the caller.
  1166. *
  1167. * When NULL is provided in second argument fit_conf_get_node() will search
  1168. * for a default configuration node instead. Default configuration node unit
  1169. * name is retrived from FIT_DEFAULT_PROP property of the '/configurations'
  1170. * node.
  1171. *
  1172. * returns:
  1173. * configuration node offset when found (>=0)
  1174. * negative number on failure (FDT_ERR_* code)
  1175. */
  1176. int fit_conf_get_node(const void *fit, const char *conf_uname)
  1177. {
  1178. int noffset, confs_noffset;
  1179. int len;
  1180. confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
  1181. if (confs_noffset < 0) {
  1182. debug("Can't find configurations parent node '%s' (%s)\n",
  1183. FIT_CONFS_PATH, fdt_strerror(confs_noffset));
  1184. return confs_noffset;
  1185. }
  1186. if (conf_uname == NULL) {
  1187. /* get configuration unit name from the default property */
  1188. debug("No configuration specified, trying default...\n");
  1189. conf_uname = (char *)fdt_getprop(fit, confs_noffset,
  1190. FIT_DEFAULT_PROP, &len);
  1191. if (conf_uname == NULL) {
  1192. fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
  1193. len);
  1194. return len;
  1195. }
  1196. debug("Found default configuration: '%s'\n", conf_uname);
  1197. }
  1198. noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
  1199. if (noffset < 0) {
  1200. debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
  1201. conf_uname, fdt_strerror(noffset));
  1202. }
  1203. return noffset;
  1204. }
  1205. int fit_conf_get_prop_node(const void *fit, int noffset,
  1206. const char *prop_name)
  1207. {
  1208. char *uname;
  1209. int len;
  1210. /* get kernel image unit name from configuration kernel property */
  1211. uname = (char *)fdt_getprop(fit, noffset, prop_name, &len);
  1212. if (uname == NULL)
  1213. return len;
  1214. return fit_image_get_node(fit, uname);
  1215. }
  1216. /**
  1217. * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
  1218. * a given configuration
  1219. * @fit: pointer to the FIT format image header
  1220. * @noffset: configuration node offset
  1221. *
  1222. * fit_conf_get_kernel_node() retrives kernel image node unit name from
  1223. * configuration FIT_KERNEL_PROP property and translates it to the node
  1224. * offset.
  1225. *
  1226. * returns:
  1227. * image node offset when found (>=0)
  1228. * negative number on failure (FDT_ERR_* code)
  1229. */
  1230. int fit_conf_get_kernel_node(const void *fit, int noffset)
  1231. {
  1232. return fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP);
  1233. }
  1234. /**
  1235. * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
  1236. * a given configuration
  1237. * @fit: pointer to the FIT format image header
  1238. * @noffset: configuration node offset
  1239. *
  1240. * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
  1241. * configuration FIT_KERNEL_PROP property and translates it to the node
  1242. * offset.
  1243. *
  1244. * returns:
  1245. * image node offset when found (>=0)
  1246. * negative number on failure (FDT_ERR_* code)
  1247. */
  1248. int fit_conf_get_ramdisk_node(const void *fit, int noffset)
  1249. {
  1250. return fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP);
  1251. }
  1252. /**
  1253. * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
  1254. * a given configuration
  1255. * @fit: pointer to the FIT format image header
  1256. * @noffset: configuration node offset
  1257. *
  1258. * fit_conf_get_fdt_node() retrives fdt image node unit name from
  1259. * configuration FIT_KERNEL_PROP property and translates it to the node
  1260. * offset.
  1261. *
  1262. * returns:
  1263. * image node offset when found (>=0)
  1264. * negative number on failure (FDT_ERR_* code)
  1265. */
  1266. int fit_conf_get_fdt_node(const void *fit, int noffset)
  1267. {
  1268. return fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP);
  1269. }
  1270. /**
  1271. * fit_conf_print - prints out the FIT configuration details
  1272. * @fit: pointer to the FIT format image header
  1273. * @noffset: offset of the configuration node
  1274. * @p: pointer to prefix string
  1275. *
  1276. * fit_conf_print() lists all mandatory properies for the processed
  1277. * configuration node.
  1278. *
  1279. * returns:
  1280. * no returned results
  1281. */
  1282. void fit_conf_print(const void *fit, int noffset, const char *p)
  1283. {
  1284. char *desc;
  1285. char *uname;
  1286. int ret;
  1287. /* Mandatory properties */
  1288. ret = fit_get_desc(fit, noffset, &desc);
  1289. printf("%s Description: ", p);
  1290. if (ret)
  1291. printf("unavailable\n");
  1292. else
  1293. printf("%s\n", desc);
  1294. uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
  1295. printf("%s Kernel: ", p);
  1296. if (uname == NULL)
  1297. printf("unavailable\n");
  1298. else
  1299. printf("%s\n", uname);
  1300. /* Optional properties */
  1301. uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
  1302. if (uname)
  1303. printf("%s Init Ramdisk: %s\n", p, uname);
  1304. uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL);
  1305. if (uname)
  1306. printf("%s FDT: %s\n", p, uname);
  1307. }
  1308. /**
  1309. * fit_check_ramdisk - verify FIT format ramdisk subimage
  1310. * @fit_hdr: pointer to the FIT ramdisk header
  1311. * @rd_noffset: ramdisk subimage node offset within FIT image
  1312. * @arch: requested ramdisk image architecture type
  1313. * @verify: data CRC verification flag
  1314. *
  1315. * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
  1316. * specified FIT image.
  1317. *
  1318. * returns:
  1319. * 1, on success
  1320. * 0, on failure
  1321. */
  1322. int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
  1323. int verify)
  1324. {
  1325. fit_image_print(fit, rd_noffset, " ");
  1326. if (verify) {
  1327. puts(" Verifying Hash Integrity ... ");
  1328. if (!fit_image_verify(fit, rd_noffset)) {
  1329. puts("Bad Data Hash\n");
  1330. bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH);
  1331. return 0;
  1332. }
  1333. puts("OK\n");
  1334. }
  1335. bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
  1336. if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) ||
  1337. !fit_image_check_arch(fit, rd_noffset, arch) ||
  1338. !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) {
  1339. printf("No Linux %s Ramdisk Image\n",
  1340. genimg_get_arch_name(arch));
  1341. bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
  1342. return 0;
  1343. }
  1344. bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK);
  1345. return 1;
  1346. }