rkcommon.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. *
  6. * (C) 2017 Theobroma Systems Design und Consulting GmbH
  7. *
  8. * Helper functions for Rockchip images
  9. */
  10. #include "imagetool.h"
  11. #include <image.h>
  12. #include <u-boot/sha256.h>
  13. #include <rc4.h>
  14. #include "mkimage.h"
  15. #include "rkcommon.h"
  16. enum {
  17. RK_MAGIC = 0x0ff0aa55,
  18. RK_MAGIC_V2 = 0x534E4B52,
  19. };
  20. enum {
  21. RK_HEADER_V1 = 1,
  22. RK_HEADER_V2 = 2,
  23. };
  24. enum hash_type {
  25. HASH_NONE = 0,
  26. HASH_SHA256 = 1,
  27. HASH_SHA512 = 2,
  28. };
  29. /**
  30. * struct image_entry
  31. *
  32. * @size_and_off: [31:16]image size;[15:0]image offset
  33. * @address: default as 0xFFFFFFFF
  34. * @flag: no use
  35. * @counter: no use
  36. * @hash: hash of image
  37. *
  38. */
  39. struct image_entry {
  40. uint32_t size_and_off;
  41. uint32_t address;
  42. uint32_t flag;
  43. uint32_t counter;
  44. uint8_t reserved[8];
  45. uint8_t hash[64];
  46. };
  47. /**
  48. * struct header0_info_v2 - v2 header block for rockchip BootRom
  49. *
  50. * This is stored at SD card block 64 (where each block is 512 bytes)
  51. *
  52. * @magic: Magic (must be RK_MAGIC_V2)
  53. * @size_and_nimage: [31:16]number of images;[15:0]
  54. * offset to hash field of header(unit as 4Byte)
  55. * @boot_flag: [3:0]hash type(0:none,1:sha256,2:sha512)
  56. * @signature: hash or signature for header info
  57. *
  58. */
  59. struct header0_info_v2 {
  60. uint32_t magic;
  61. uint8_t reserved[4];
  62. uint32_t size_and_nimage;
  63. uint32_t boot_flag;
  64. uint8_t reserved1[104];
  65. struct image_entry images[4];
  66. uint8_t reserved2[1064];
  67. uint8_t hash[512];
  68. };
  69. /**
  70. * struct header0_info - header block for boot ROM
  71. *
  72. * This is stored at SD card block 64 (where each block is 512 bytes, or at
  73. * the start of SPI flash. It is encoded with RC4.
  74. *
  75. * @magic: Magic (must be RK_MAGIC)
  76. * @disable_rc4: 0 to use rc4 for boot image, 1 to use plain binary
  77. * @init_offset: Offset in blocks of the SPL code from this header
  78. * block. E.g. 4 means 2KB after the start of this header.
  79. * Other fields are not used by U-Boot
  80. */
  81. struct header0_info {
  82. uint32_t magic;
  83. uint8_t reserved[4];
  84. uint32_t disable_rc4;
  85. uint16_t init_offset;
  86. uint8_t reserved1[492];
  87. uint16_t init_size;
  88. uint16_t init_boot_size;
  89. uint8_t reserved2[2];
  90. };
  91. /**
  92. * struct header1_info
  93. */
  94. struct header1_info {
  95. uint32_t magic;
  96. };
  97. /**
  98. * struct spl_info - spl info for each chip
  99. *
  100. * @imagename: Image name(passed by "mkimage -n")
  101. * @spl_hdr: Boot ROM requires a 4-bytes spl header
  102. * @spl_size: Spl size(include extra 4-bytes spl header)
  103. * @spl_rc4: RC4 encode the SPL binary (same key as header)
  104. * @header_ver: header block version
  105. */
  106. struct spl_info {
  107. const char *imagename;
  108. const char *spl_hdr;
  109. const uint32_t spl_size;
  110. const bool spl_rc4;
  111. const uint32_t header_ver;
  112. };
  113. static struct spl_info spl_infos[] = {
  114. { "px30", "RK33", 0x2800, false, RK_HEADER_V1 },
  115. { "rk3036", "RK30", 0x1000, false, RK_HEADER_V1 },
  116. { "rk3128", "RK31", 0x1800, false, RK_HEADER_V1 },
  117. { "rk3188", "RK31", 0x8000 - 0x800, true, RK_HEADER_V1 },
  118. { "rk322x", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
  119. { "rk3288", "RK32", 0x8000, false, RK_HEADER_V1 },
  120. { "rk3308", "RK33", 0x40000 - 0x1000, false, RK_HEADER_V1 },
  121. { "rk3328", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
  122. { "rk3368", "RK33", 0x8000 - 0x1000, false, RK_HEADER_V1 },
  123. { "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 },
  124. { "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
  125. { "rk3568", "RK35", 0x14000 - 0x1000, false, RK_HEADER_V2 },
  126. };
  127. /**
  128. * struct spl_params - spl params parsed in check_params()
  129. *
  130. * @init_file: Init data file path
  131. * @init_size: Aligned size of init data in bytes
  132. * @boot_file: Boot data file path
  133. * @boot_size: Aligned size of boot data in bytes
  134. */
  135. struct spl_params {
  136. char *init_file;
  137. uint32_t init_size;
  138. char *boot_file;
  139. uint32_t boot_size;
  140. };
  141. static struct spl_params spl_params = { 0 };
  142. static unsigned char rc4_key[16] = {
  143. 124, 78, 3, 4, 85, 5, 9, 7,
  144. 45, 44, 123, 56, 23, 13, 23, 17
  145. };
  146. static struct spl_info *rkcommon_get_spl_info(char *imagename)
  147. {
  148. int i;
  149. if (!imagename)
  150. return NULL;
  151. for (i = 0; i < ARRAY_SIZE(spl_infos); i++)
  152. if (!strncmp(imagename, spl_infos[i].imagename, 6))
  153. return spl_infos + i;
  154. return NULL;
  155. }
  156. static int rkcommon_get_aligned_size(struct image_tool_params *params,
  157. const char *fname)
  158. {
  159. int size;
  160. size = imagetool_get_filesize(params, fname);
  161. if (size < 0)
  162. return -1;
  163. /*
  164. * Pad to a 2KB alignment, as required for init/boot size by the ROM
  165. * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html)
  166. */
  167. return ROUND(size, RK_SIZE_ALIGN);
  168. }
  169. int rkcommon_check_params(struct image_tool_params *params)
  170. {
  171. int i, size;
  172. /*
  173. * If this is a operation (list or extract), the don't require
  174. * imagename to be set.
  175. */
  176. if (params->lflag || params->iflag)
  177. return EXIT_SUCCESS;
  178. if (!rkcommon_get_spl_info(params->imagename))
  179. goto err_spl_info;
  180. spl_params.init_file = params->datafile;
  181. spl_params.boot_file = strchr(spl_params.init_file, ':');
  182. if (spl_params.boot_file) {
  183. *spl_params.boot_file = '\0';
  184. spl_params.boot_file += 1;
  185. }
  186. size = rkcommon_get_aligned_size(params, spl_params.init_file);
  187. if (size < 0)
  188. return EXIT_FAILURE;
  189. spl_params.init_size = size;
  190. /* Boot file is optional, and only for back-to-bootrom functionality. */
  191. if (spl_params.boot_file) {
  192. size = rkcommon_get_aligned_size(params, spl_params.boot_file);
  193. if (size < 0)
  194. return EXIT_FAILURE;
  195. spl_params.boot_size = size;
  196. }
  197. if (spl_params.init_size > rkcommon_get_spl_size(params)) {
  198. fprintf(stderr,
  199. "Error: SPL image is too large (size %#x than %#x)\n",
  200. spl_params.init_size, rkcommon_get_spl_size(params));
  201. return EXIT_FAILURE;
  202. }
  203. return EXIT_SUCCESS;
  204. err_spl_info:
  205. fprintf(stderr, "ERROR: imagename (%s) is not supported!\n",
  206. params->imagename ? params->imagename : "NULL");
  207. fprintf(stderr, "Available imagename:");
  208. for (i = 0; i < ARRAY_SIZE(spl_infos); i++)
  209. fprintf(stderr, "\t%s", spl_infos[i].imagename);
  210. fprintf(stderr, "\n");
  211. return EXIT_FAILURE;
  212. }
  213. const char *rkcommon_get_spl_hdr(struct image_tool_params *params)
  214. {
  215. struct spl_info *info = rkcommon_get_spl_info(params->imagename);
  216. /*
  217. * info would not be NULL, because of we checked params before.
  218. */
  219. return info->spl_hdr;
  220. }
  221. int rkcommon_get_spl_size(struct image_tool_params *params)
  222. {
  223. struct spl_info *info = rkcommon_get_spl_info(params->imagename);
  224. /*
  225. * info would not be NULL, because of we checked params before.
  226. */
  227. return info->spl_size;
  228. }
  229. bool rkcommon_need_rc4_spl(struct image_tool_params *params)
  230. {
  231. struct spl_info *info = rkcommon_get_spl_info(params->imagename);
  232. /*
  233. * info would not be NULL, because of we checked params before.
  234. */
  235. return info->spl_rc4;
  236. }
  237. bool rkcommon_is_header_v2(struct image_tool_params *params)
  238. {
  239. struct spl_info *info = rkcommon_get_spl_info(params->imagename);
  240. return (info->header_ver == RK_HEADER_V2);
  241. }
  242. static void do_sha256_hash(uint8_t *buf, uint32_t size, uint8_t *out)
  243. {
  244. sha256_context ctx;
  245. sha256_starts(&ctx);
  246. sha256_update(&ctx, buf, size);
  247. sha256_finish(&ctx, out);
  248. }
  249. static void rkcommon_set_header0(void *buf, struct image_tool_params *params)
  250. {
  251. struct header0_info *hdr = buf;
  252. uint32_t init_boot_size;
  253. memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
  254. hdr->magic = cpu_to_le32(RK_MAGIC);
  255. hdr->disable_rc4 = cpu_to_le32(!rkcommon_need_rc4_spl(params));
  256. hdr->init_offset = cpu_to_le16(RK_INIT_OFFSET);
  257. hdr->init_size = cpu_to_le16(spl_params.init_size / RK_BLK_SIZE);
  258. /*
  259. * init_boot_size needs to be set, as it is read by the BootROM
  260. * to determine the size of the next-stage bootloader (e.g. U-Boot
  261. * proper), when used with the back-to-bootrom functionality.
  262. *
  263. * see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html
  264. * for a more detailed explanation by Andy Yan
  265. */
  266. if (spl_params.boot_file)
  267. init_boot_size = spl_params.init_size + spl_params.boot_size;
  268. else
  269. init_boot_size = spl_params.init_size + RK_MAX_BOOT_SIZE;
  270. hdr->init_boot_size = cpu_to_le16(init_boot_size / RK_BLK_SIZE);
  271. rc4_encode(buf, RK_BLK_SIZE, rc4_key);
  272. }
  273. static void rkcommon_set_header0_v2(void *buf, struct image_tool_params *params)
  274. {
  275. struct header0_info_v2 *hdr = buf;
  276. uint32_t sector_offset, image_sector_count;
  277. uint32_t image_size_array[2];
  278. uint8_t *image_ptr = NULL;
  279. int i;
  280. printf("Image Type: Rockchip %s boot image\n",
  281. rkcommon_get_spl_hdr(params));
  282. memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
  283. hdr->magic = cpu_to_le32(RK_MAGIC_V2);
  284. hdr->size_and_nimage = cpu_to_le32((2 << 16) + 384);
  285. hdr->boot_flag = cpu_to_le32(HASH_SHA256);
  286. sector_offset = 4;
  287. image_size_array[0] = spl_params.init_size;
  288. image_size_array[1] = spl_params.boot_size;
  289. for (i = 0; i < 2; i++) {
  290. image_sector_count = image_size_array[i] / RK_BLK_SIZE;
  291. hdr->images[i].size_and_off = cpu_to_le32((image_sector_count
  292. << 16) + sector_offset);
  293. hdr->images[i].address = 0xFFFFFFFF;
  294. hdr->images[i].counter = cpu_to_le32(i + 1);
  295. image_ptr = buf + sector_offset * RK_BLK_SIZE;
  296. do_sha256_hash(image_ptr, image_size_array[i],
  297. hdr->images[i].hash);
  298. sector_offset = sector_offset + image_sector_count;
  299. }
  300. do_sha256_hash(buf, (void *)hdr->hash - buf, hdr->hash);
  301. }
  302. void rkcommon_set_header(void *buf, struct stat *sbuf, int ifd,
  303. struct image_tool_params *params)
  304. {
  305. struct header1_info *hdr = buf + RK_SPL_HDR_START;
  306. if (rkcommon_is_header_v2(params)) {
  307. rkcommon_set_header0_v2(buf, params);
  308. } else {
  309. rkcommon_set_header0(buf, params);
  310. /* Set up the SPL name (i.e. copy spl_hdr over) */
  311. if (memcmp(&hdr->magic, "RSAK", 4))
  312. memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
  313. if (rkcommon_need_rc4_spl(params))
  314. rkcommon_rc4_encode_spl(buf, RK_SPL_HDR_START,
  315. spl_params.init_size);
  316. if (spl_params.boot_file) {
  317. if (rkcommon_need_rc4_spl(params))
  318. rkcommon_rc4_encode_spl(buf + RK_SPL_HDR_START,
  319. spl_params.init_size,
  320. spl_params.boot_size);
  321. }
  322. }
  323. }
  324. static inline unsigned int rkcommon_offset_to_spi(unsigned int offset)
  325. {
  326. /*
  327. * While SD/MMC images use a flat addressing, SPI images are padded
  328. * to use the first 2K of every 4K sector only.
  329. */
  330. return ((offset & ~0x7ff) << 1) + (offset & 0x7ff);
  331. }
  332. static int rkcommon_parse_header(const void *buf, struct header0_info *header0,
  333. struct spl_info **spl_info)
  334. {
  335. unsigned int hdr1_offset;
  336. struct header1_info *hdr1_sdmmc, *hdr1_spi;
  337. int i;
  338. if (spl_info)
  339. *spl_info = NULL;
  340. /*
  341. * The first header (hdr0) is always RC4 encoded, so try to decrypt
  342. * with the well-known key.
  343. */
  344. memcpy((void *)header0, buf, sizeof(struct header0_info));
  345. rc4_encode((void *)header0, sizeof(struct header0_info), rc4_key);
  346. if (le32_to_cpu(header0->magic) != RK_MAGIC)
  347. return -EPROTO;
  348. /* We don't support RC4 encoded image payloads here, yet... */
  349. if (le32_to_cpu(header0->disable_rc4) == 0)
  350. return -ENOSYS;
  351. hdr1_offset = le16_to_cpu(header0->init_offset) * RK_BLK_SIZE;
  352. hdr1_sdmmc = (struct header1_info *)(buf + hdr1_offset);
  353. hdr1_spi = (struct header1_info *)(buf +
  354. rkcommon_offset_to_spi(hdr1_offset));
  355. for (i = 0; i < ARRAY_SIZE(spl_infos); i++) {
  356. if (!memcmp(&hdr1_sdmmc->magic, spl_infos[i].spl_hdr,
  357. RK_SPL_HDR_SIZE)) {
  358. if (spl_info)
  359. *spl_info = &spl_infos[i];
  360. return IH_TYPE_RKSD;
  361. } else if (!memcmp(&hdr1_spi->magic, spl_infos[i].spl_hdr,
  362. RK_SPL_HDR_SIZE)) {
  363. if (spl_info)
  364. *spl_info = &spl_infos[i];
  365. return IH_TYPE_RKSPI;
  366. }
  367. }
  368. return -1;
  369. }
  370. static int rkcommon_parse_header_v2(const void *buf, struct header0_info_v2 *header)
  371. {
  372. memcpy((void *)header, buf, sizeof(struct header0_info_v2));
  373. if (le32_to_cpu(header->magic) != RK_MAGIC_V2)
  374. return -EPROTO;
  375. return 0;
  376. }
  377. int rkcommon_verify_header(unsigned char *buf, int size,
  378. struct image_tool_params *params)
  379. {
  380. struct header0_info header0;
  381. struct spl_info *img_spl_info, *spl_info;
  382. int ret;
  383. ret = rkcommon_parse_header(buf, &header0, &img_spl_info);
  384. /* If this is the (unimplemented) RC4 case, then rewrite the result */
  385. if (ret == -ENOSYS)
  386. return 0;
  387. if (ret < 0)
  388. return ret;
  389. /*
  390. * If no 'imagename' is specified via the commandline (e.g. if this is
  391. * 'dumpimage -l' w/o any further constraints), we accept any spl_info.
  392. */
  393. if (params->imagename == NULL)
  394. return 0;
  395. /* Match the 'imagename' against the 'spl_hdr' found */
  396. spl_info = rkcommon_get_spl_info(params->imagename);
  397. if (spl_info && img_spl_info)
  398. return strcmp(spl_info->spl_hdr, img_spl_info->spl_hdr);
  399. return -ENOENT;
  400. }
  401. void rkcommon_print_header(const void *buf)
  402. {
  403. struct header0_info header0;
  404. struct header0_info_v2 header0_v2;
  405. struct spl_info *spl_info;
  406. uint8_t image_type;
  407. int ret, boot_size, init_size;
  408. if ((*(uint32_t *)buf) == RK_MAGIC_V2) {
  409. ret = rkcommon_parse_header_v2(buf, &header0_v2);
  410. if (ret < 0) {
  411. fprintf(stderr, "Error: image verification failed\n");
  412. return;
  413. }
  414. init_size = header0_v2.images[0].size_and_off >> 16;
  415. init_size = init_size * RK_BLK_SIZE;
  416. boot_size = header0_v2.images[1].size_and_off >> 16;
  417. boot_size = boot_size * RK_BLK_SIZE;
  418. } else {
  419. ret = rkcommon_parse_header(buf, &header0, &spl_info);
  420. /* If this is the (unimplemented) RC4 case, then fail silently */
  421. if (ret == -ENOSYS)
  422. return;
  423. if (ret < 0) {
  424. fprintf(stderr, "Error: image verification failed\n");
  425. return;
  426. }
  427. image_type = ret;
  428. init_size = header0.init_size * RK_BLK_SIZE;
  429. boot_size = header0.init_boot_size * RK_BLK_SIZE - init_size;
  430. printf("Image Type: Rockchip %s (%s) boot image\n",
  431. spl_info->spl_hdr,
  432. (image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI");
  433. }
  434. printf("Init Data Size: %d bytes\n", init_size);
  435. if (boot_size != RK_MAX_BOOT_SIZE)
  436. printf("Boot Data Size: %d bytes\n", boot_size);
  437. }
  438. void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
  439. {
  440. unsigned int remaining = size;
  441. while (remaining > 0) {
  442. int step = (remaining > RK_BLK_SIZE) ? RK_BLK_SIZE : remaining;
  443. rc4_encode(buf + offset, step, rc4_key);
  444. offset += RK_BLK_SIZE;
  445. remaining -= step;
  446. }
  447. }
  448. int rkcommon_vrec_header(struct image_tool_params *params,
  449. struct image_type_params *tparams)
  450. {
  451. /*
  452. * The SPL image looks as follows:
  453. *
  454. * 0x0 header0 (see rkcommon.c)
  455. * 0x800 spl_name ('RK30', ..., 'RK33')
  456. * (start of the payload for AArch64 payloads: we expect the
  457. * first 4 bytes to be available for overwriting with our
  458. * spl_name)
  459. * 0x804 first instruction to be executed
  460. * (start of the image/payload for 32bit payloads)
  461. *
  462. * For AArch64 (ARMv8) payloads, natural alignment (8-bytes) is
  463. * required for its sections (so the image we receive needs to
  464. * have the first 4 bytes reserved for the spl_name). Reserving
  465. * these 4 bytes is done using the BOOT0_HOOK infrastructure.
  466. *
  467. * The header is always at 0x800 (as we now use a payload
  468. * prepadded using the boot0 hook for all targets): the first
  469. * 4 bytes of these images can safely be overwritten using the
  470. * boot magic.
  471. */
  472. tparams->header_size = RK_SPL_HDR_START;
  473. /* Allocate, clear and install the header */
  474. tparams->hdr = malloc(tparams->header_size);
  475. if (!tparams->hdr) {
  476. fprintf(stderr, "%s: Can't alloc header: %s\n",
  477. params->cmdname, strerror(errno));
  478. exit(EXIT_FAILURE);
  479. }
  480. memset(tparams->hdr, 0, tparams->header_size);
  481. /*
  482. * We need to store the original file-size (i.e. before padding), as
  483. * imagetool does not set this during its adjustment of file_size.
  484. */
  485. params->orig_file_size = tparams->header_size +
  486. spl_params.init_size + spl_params.boot_size;
  487. params->file_size = ROUND(params->orig_file_size, RK_SIZE_ALIGN);
  488. /* Ignoring pad len, since we are using our own copy_image() */
  489. return 0;
  490. }
  491. static int pad_file(struct image_tool_params *params, int ifd, int pad)
  492. {
  493. uint8_t zeros[4096];
  494. memset(zeros, 0, sizeof(zeros));
  495. while (pad > 0) {
  496. int todo = sizeof(zeros);
  497. if (todo > pad)
  498. todo = pad;
  499. if (write(ifd, (char *)&zeros, todo) != todo) {
  500. fprintf(stderr, "%s: Write error on %s: %s\n",
  501. params->cmdname, params->imagefile,
  502. strerror(errno));
  503. return -1;
  504. }
  505. pad -= todo;
  506. }
  507. return 0;
  508. }
  509. static int copy_file(struct image_tool_params *params, int ifd,
  510. const char *file, int padded_size)
  511. {
  512. int dfd;
  513. struct stat sbuf;
  514. unsigned char *ptr;
  515. int size;
  516. if (params->vflag)
  517. fprintf(stderr, "Adding Image %s\n", file);
  518. dfd = open(file, O_RDONLY | O_BINARY);
  519. if (dfd < 0) {
  520. fprintf(stderr, "%s: Can't open %s: %s\n",
  521. params->cmdname, file, strerror(errno));
  522. return -1;
  523. }
  524. if (fstat(dfd, &sbuf) < 0) {
  525. fprintf(stderr, "%s: Can't stat %s: %s\n",
  526. params->cmdname, file, strerror(errno));
  527. goto err_close;
  528. }
  529. if (params->vflag)
  530. fprintf(stderr, "Size %u(pad to %u)\n",
  531. (int)sbuf.st_size, padded_size);
  532. ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
  533. if (ptr == MAP_FAILED) {
  534. fprintf(stderr, "%s: Can't read %s: %s\n",
  535. params->cmdname, file, strerror(errno));
  536. goto err_munmap;
  537. }
  538. size = sbuf.st_size;
  539. if (write(ifd, ptr, size) != size) {
  540. fprintf(stderr, "%s: Write error on %s: %s\n",
  541. params->cmdname, params->imagefile, strerror(errno));
  542. goto err_munmap;
  543. }
  544. munmap((void *)ptr, sbuf.st_size);
  545. close(dfd);
  546. return pad_file(params, ifd, padded_size - size);
  547. err_munmap:
  548. munmap((void *)ptr, sbuf.st_size);
  549. err_close:
  550. close(dfd);
  551. return -1;
  552. }
  553. int rockchip_copy_image(int ifd, struct image_tool_params *params)
  554. {
  555. int ret;
  556. ret = copy_file(params, ifd, spl_params.init_file,
  557. spl_params.init_size);
  558. if (ret)
  559. return ret;
  560. if (spl_params.boot_file) {
  561. ret = copy_file(params, ifd, spl_params.boot_file,
  562. spl_params.boot_size);
  563. if (ret)
  564. return ret;
  565. }
  566. return pad_file(params, ifd,
  567. params->file_size - params->orig_file_size);
  568. }