123ba6841SJoseph Chen /*
223ba6841SJoseph Chen * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
323ba6841SJoseph Chen *
423ba6841SJoseph Chen * SPDX-License-Identifier: GPL-2.0+
523ba6841SJoseph Chen */
623ba6841SJoseph Chen #include "compiler.h"
723ba6841SJoseph Chen #include <version.h>
823ba6841SJoseph Chen #include "sha.h"
923ba6841SJoseph Chen #include <u-boot/sha256.h>
1023ba6841SJoseph Chen #include <u-boot/crc.h>
1123ba6841SJoseph Chen #include <linux/sizes.h>
1223ba6841SJoseph Chen #include <linux/kconfig.h>
1323ba6841SJoseph Chen #include <config.h>
1423ba6841SJoseph Chen
1523ba6841SJoseph Chen extern uint32_t crc32_rk(uint32_t, const unsigned char *, uint32_t);
1623ba6841SJoseph Chen
1723ba6841SJoseph Chen #define OPT_PACK "--pack"
1823ba6841SJoseph Chen #define OPT_UNPACK "--unpack"
1923ba6841SJoseph Chen #define OPT_UBOOT "--uboot"
2023ba6841SJoseph Chen #define OPT_TRUSTOS "--trustos"
21*c64e2562SYifeng Zhao #define OPT_KERNEL "--kernel"
2223ba6841SJoseph Chen #define OPT_SIZE "--size"
2323ba6841SJoseph Chen #define OPT_VERSION "--version"
2423ba6841SJoseph Chen #define OPT_INFO "--info"
2552243bceSJoseph Chen #define OPT_PREPATH "--prepath"
2623ba6841SJoseph Chen
2723ba6841SJoseph Chen /* pack or unpack */
2823ba6841SJoseph Chen #define MODE_PACK 0
2923ba6841SJoseph Chen #define MODE_UNPACK 1
3023ba6841SJoseph Chen #define MODE_INFO 2
3123ba6841SJoseph Chen #define CONFIG_SECUREBOOT_SHA256
3223ba6841SJoseph Chen
3323ba6841SJoseph Chen /* image type */
3423ba6841SJoseph Chen #define IMAGE_UBOOT 0
3523ba6841SJoseph Chen #define IMAGE_TRUST 1
36*c64e2562SYifeng Zhao #define IMAGE_KERNEL 2
3723ba6841SJoseph Chen
3823ba6841SJoseph Chen /* magic and hash size */
3923ba6841SJoseph Chen #define LOADER_MAGIC_SIZE 8
4023ba6841SJoseph Chen #define LOADER_HASH_SIZE 32
4123ba6841SJoseph Chen
4223ba6841SJoseph Chen /* uboot image config */
4323ba6841SJoseph Chen #define UBOOT_NAME "uboot"
4423ba6841SJoseph Chen #ifdef CONFIG_RK_NVME_BOOT_EN
4523ba6841SJoseph Chen #define UBOOT_NUM 2
4623ba6841SJoseph Chen #define UBOOT_MAX_SIZE 512 * 1024
4723ba6841SJoseph Chen #else
4823ba6841SJoseph Chen #define UBOOT_NUM 4
4923ba6841SJoseph Chen #define UBOOT_MAX_SIZE 1024 * 1024
5023ba6841SJoseph Chen #endif
5123ba6841SJoseph Chen
5223ba6841SJoseph Chen #define UBOOT_VERSION_STRING \
5323ba6841SJoseph Chen U_BOOT_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME ")" CONFIG_IDENT_STRING
5423ba6841SJoseph Chen
5523ba6841SJoseph Chen #define RK_UBOOT_MAGIC "LOADER "
5623ba6841SJoseph Chen #define RK_UBOOT_RUNNING_ADDR CONFIG_SYS_TEXT_BASE
5723ba6841SJoseph Chen
5823ba6841SJoseph Chen /* trust image config */
5923ba6841SJoseph Chen #define TRUST_NAME "trustos"
6023ba6841SJoseph Chen #define TRUST_NUM 4
6123ba6841SJoseph Chen #define TRUST_MAX_SIZE 1024 * 1024
6223ba6841SJoseph Chen #define TRUST_VERSION_STRING "Trust os"
6323ba6841SJoseph Chen
6423ba6841SJoseph Chen #define RK_TRUST_MAGIC "TOS "
6523ba6841SJoseph Chen #define RK_TRUST_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_128M + SZ_4M)
6623ba6841SJoseph Chen
67*c64e2562SYifeng Zhao #define KERNEL_NAME "kernel"
68*c64e2562SYifeng Zhao #define KERNEL_NUM 1
69*c64e2562SYifeng Zhao #define KERNEL_MAX_SIZE 30720 * 1024
70*c64e2562SYifeng Zhao #define KERNEL_VERSION_STRING "kernel os"
71*c64e2562SYifeng Zhao
72*c64e2562SYifeng Zhao #define RK_KERNEL_MAGIC "KERNEL"
73*c64e2562SYifeng Zhao #define RK_KERNEL_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_4M)
74*c64e2562SYifeng Zhao
7523ba6841SJoseph Chen typedef struct tag_second_loader_hdr {
7623ba6841SJoseph Chen uint8_t magic[LOADER_MAGIC_SIZE]; /* magic */
7723ba6841SJoseph Chen uint32_t version;
7823ba6841SJoseph Chen uint32_t reserved0;
7923ba6841SJoseph Chen uint32_t loader_load_addr; /* physical load addr */
8023ba6841SJoseph Chen uint32_t loader_load_size; /* size in bytes */
8123ba6841SJoseph Chen uint32_t crc32; /* crc32 */
8223ba6841SJoseph Chen uint32_t hash_len; /* 20 or 32 , 0 is no hash */
8323ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE]; /* sha */
8423ba6841SJoseph Chen
85*c64e2562SYifeng Zhao unsigned int js_hash; /*js hsah*/
86*c64e2562SYifeng Zhao unsigned char reserved[1024-32-32-4];
8723ba6841SJoseph Chen uint32_t signTag; /* 0x4E474953 */
8823ba6841SJoseph Chen uint32_t signlen; /* maybe 128 or 256 */
8923ba6841SJoseph Chen uint8_t rsaHash[256]; /* maybe 128 or 256, using max size 256 */
9023ba6841SJoseph Chen uint8_t reserved2[2048 - 1024 - 256 - 8];
9123ba6841SJoseph Chen } second_loader_hdr;
9223ba6841SJoseph Chen
usage(const char * prog)9323ba6841SJoseph Chen void usage(const char *prog)
9423ba6841SJoseph Chen {
95*c64e2562SYifeng Zhao fprintf(stderr, "Usage: %s [--pack|--unpack] [--uboot|--trustos|--kernel]\
9623ba6841SJoseph Chen file_in "
9723ba6841SJoseph Chen "file_out [load_addr] [--size] [size number]\
9823ba6841SJoseph Chen [--version] "
9923ba6841SJoseph Chen "[version] | [--info] [file]\n",
10023ba6841SJoseph Chen prog);
10123ba6841SJoseph Chen }
10223ba6841SJoseph Chen
str2hex(char * str)10323ba6841SJoseph Chen unsigned int str2hex(char *str)
10423ba6841SJoseph Chen {
10523ba6841SJoseph Chen int i = 0;
10623ba6841SJoseph Chen unsigned int value = 0;
10723ba6841SJoseph Chen
10823ba6841SJoseph Chen if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X'))
10923ba6841SJoseph Chen str += 2;
11023ba6841SJoseph Chen if (*str == 'x' || *str == 'X')
11123ba6841SJoseph Chen str += 1;
11223ba6841SJoseph Chen
11323ba6841SJoseph Chen for (i = 0; *str != '\0'; i++, ++str) {
11423ba6841SJoseph Chen if (*str >= '0' && *str <= '9')
11523ba6841SJoseph Chen value = value * 16 + *str - '0';
11623ba6841SJoseph Chen else if (*str >= 'a' && *str <= 'f')
11723ba6841SJoseph Chen value = value * 16 + *str - 'a' + 10;
11823ba6841SJoseph Chen else if (*str >= 'A' && *str <= 'F')
11923ba6841SJoseph Chen value = value * 16 + *str - 'A' + 10;
12023ba6841SJoseph Chen else
12123ba6841SJoseph Chen break;
12223ba6841SJoseph Chen }
12323ba6841SJoseph Chen return value;
12423ba6841SJoseph Chen }
12523ba6841SJoseph Chen
js_hash(uint8_t * buf,uint32_t len)126*c64e2562SYifeng Zhao static uint32_t js_hash(uint8_t *buf, uint32_t len)
127*c64e2562SYifeng Zhao {
128*c64e2562SYifeng Zhao uint32_t hash = 0x47C6A7E6;
129*c64e2562SYifeng Zhao uint32_t i;
130*c64e2562SYifeng Zhao
131*c64e2562SYifeng Zhao for (i = 0; i < len; i++)
132*c64e2562SYifeng Zhao hash ^= ((hash << 5) + buf[i] + (hash >> 2));
133*c64e2562SYifeng Zhao
134*c64e2562SYifeng Zhao return hash;
135*c64e2562SYifeng Zhao }
136*c64e2562SYifeng Zhao
main(int argc,char * argv[])13723ba6841SJoseph Chen int main(int argc, char *argv[])
13823ba6841SJoseph Chen {
13923ba6841SJoseph Chen int mode = -1, image = -1;
14023ba6841SJoseph Chen int max_size, max_num;
14123ba6841SJoseph Chen int size, i;
14223ba6841SJoseph Chen uint32_t loader_addr, in_loader_addr = -1;
14323ba6841SJoseph Chen char *magic, *version, *name;
14423ba6841SJoseph Chen FILE *fi, *fo;
14523ba6841SJoseph Chen second_loader_hdr hdr;
14623ba6841SJoseph Chen char *buf = 0;
14723ba6841SJoseph Chen uint32_t in_size = 0, in_num = 0;
14823ba6841SJoseph Chen char *file_in = NULL, *file_out = NULL;
14952243bceSJoseph Chen char *prepath = NULL;
15052243bceSJoseph Chen char file_name[1024];
15123ba6841SJoseph Chen uint32_t curr_version = 0;
15223ba6841SJoseph Chen
15323ba6841SJoseph Chen if (argc < 3) {
15423ba6841SJoseph Chen usage(argv[0]);
15523ba6841SJoseph Chen exit(EXIT_FAILURE);
15623ba6841SJoseph Chen }
15723ba6841SJoseph Chen
15823ba6841SJoseph Chen for (i = 1; i < argc; i++) {
15923ba6841SJoseph Chen if (!strcmp(argv[i], OPT_PACK)) {
16023ba6841SJoseph Chen mode = MODE_PACK;
16123ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UNPACK)) {
16223ba6841SJoseph Chen mode = MODE_UNPACK;
16323ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UBOOT)) {
16423ba6841SJoseph Chen image = IMAGE_UBOOT;
16523ba6841SJoseph Chen file_in = argv[++i];
16623ba6841SJoseph Chen file_out = argv[++i];
16723ba6841SJoseph Chen /* detect whether loader address is delivered */
16823ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
16923ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]);
17023ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_TRUSTOS)) {
17123ba6841SJoseph Chen image = IMAGE_TRUST;
17223ba6841SJoseph Chen file_in = argv[++i];
17323ba6841SJoseph Chen file_out = argv[++i];
17423ba6841SJoseph Chen /* detect whether loader address is delivered */
17523ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
17623ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]);
177*c64e2562SYifeng Zhao } else if (!strcmp(argv[i], OPT_KERNEL)) {
178*c64e2562SYifeng Zhao image = IMAGE_KERNEL;
179*c64e2562SYifeng Zhao file_in = argv[++i];
180*c64e2562SYifeng Zhao file_out = argv[++i];
181*c64e2562SYifeng Zhao /* detect whether loader address is delivered */
182*c64e2562SYifeng Zhao if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
183*c64e2562SYifeng Zhao in_loader_addr = str2hex(argv[++i]);
18423ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_SIZE)) {
18523ba6841SJoseph Chen in_size = strtoul(argv[++i], NULL, 10);
18623ba6841SJoseph Chen /*
18723ba6841SJoseph Chen * Usually, it must be at 512kb align due to preloader
18823ba6841SJoseph Chen * detects every 512kb. But some product has critial
18923ba6841SJoseph Chen * flash size requirement, we have to make it small than
19023ba6841SJoseph Chen * 512KB.
19123ba6841SJoseph Chen */
19223ba6841SJoseph Chen if (in_size % 64) {
19323ba6841SJoseph Chen usage(argv[0]);
19423ba6841SJoseph Chen exit(EXIT_FAILURE);
19523ba6841SJoseph Chen }
19623ba6841SJoseph Chen in_size *= 1024;
19723ba6841SJoseph Chen
19823ba6841SJoseph Chen in_num = strtoul(argv[++i], NULL, 10);
19923ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_VERSION)) {
20023ba6841SJoseph Chen curr_version = strtoul(argv[++i], NULL, 10);
20123ba6841SJoseph Chen printf("curr_version = 0x%x\n", curr_version);
20223ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_INFO)) {
20323ba6841SJoseph Chen mode = MODE_INFO;
20423ba6841SJoseph Chen file_in = argv[++i];
20552243bceSJoseph Chen } else if (!strcmp(argv[i], OPT_PREPATH)) {
20652243bceSJoseph Chen prepath = argv[++i];
20723ba6841SJoseph Chen } else {
20823ba6841SJoseph Chen usage(argv[0]);
20923ba6841SJoseph Chen exit(EXIT_FAILURE);
21023ba6841SJoseph Chen }
21123ba6841SJoseph Chen }
21223ba6841SJoseph Chen
21323ba6841SJoseph Chen /* config image information */
21423ba6841SJoseph Chen if (image == IMAGE_UBOOT) {
21523ba6841SJoseph Chen name = UBOOT_NAME;
21623ba6841SJoseph Chen magic = RK_UBOOT_MAGIC;
21723ba6841SJoseph Chen version = UBOOT_VERSION_STRING;
21823ba6841SJoseph Chen max_size = in_size ? in_size : UBOOT_MAX_SIZE;
21923ba6841SJoseph Chen max_num = in_num ? in_num : UBOOT_NUM;
22023ba6841SJoseph Chen loader_addr =
22123ba6841SJoseph Chen (in_loader_addr == -1) ? RK_UBOOT_RUNNING_ADDR : in_loader_addr;
22223ba6841SJoseph Chen } else if (image == IMAGE_TRUST) {
22323ba6841SJoseph Chen name = TRUST_NAME;
22423ba6841SJoseph Chen magic = RK_TRUST_MAGIC;
22523ba6841SJoseph Chen version = TRUST_VERSION_STRING;
22623ba6841SJoseph Chen max_size = in_size ? in_size : TRUST_MAX_SIZE;
22723ba6841SJoseph Chen max_num = in_num ? in_num : TRUST_NUM;
22823ba6841SJoseph Chen loader_addr =
22923ba6841SJoseph Chen (in_loader_addr == -1) ? RK_TRUST_RUNNING_ADDR : in_loader_addr;
230*c64e2562SYifeng Zhao } else if (image == IMAGE_KERNEL) {
231*c64e2562SYifeng Zhao name = KERNEL_NAME;
232*c64e2562SYifeng Zhao magic = RK_KERNEL_MAGIC;
233*c64e2562SYifeng Zhao version = KERNEL_VERSION_STRING;
234*c64e2562SYifeng Zhao max_size = in_size ? in_size : KERNEL_MAX_SIZE;
235*c64e2562SYifeng Zhao max_num = in_num ? in_num : KERNEL_NUM;
236*c64e2562SYifeng Zhao loader_addr =
237*c64e2562SYifeng Zhao (in_loader_addr == -1) ? RK_KERNEL_RUNNING_ADDR : in_loader_addr;
238*c64e2562SYifeng Zhao
23923ba6841SJoseph Chen } else if (mode == MODE_INFO) {
24023ba6841SJoseph Chen
24123ba6841SJoseph Chen } else {
24223ba6841SJoseph Chen exit(EXIT_FAILURE);
24323ba6841SJoseph Chen }
24423ba6841SJoseph Chen
24523ba6841SJoseph Chen if (mode == MODE_PACK) {
24623ba6841SJoseph Chen buf = calloc(max_size, max_num);
24723ba6841SJoseph Chen if (!buf) {
24823ba6841SJoseph Chen perror(file_out);
24923ba6841SJoseph Chen exit(EXIT_FAILURE);
25023ba6841SJoseph Chen }
25123ba6841SJoseph Chen printf("\n load addr is 0x%x!\n", loader_addr);
25252243bceSJoseph Chen
25352243bceSJoseph Chen /* Add prepath for file_in name */
25452243bceSJoseph Chen if (prepath && strncmp(prepath, file_in, strlen(prepath))) {
25552243bceSJoseph Chen strcpy(file_name, prepath);
25652243bceSJoseph Chen strcat(file_name, file_in);
25752243bceSJoseph Chen file_in = file_name;
25852243bceSJoseph Chen }
25952243bceSJoseph Chen
26023ba6841SJoseph Chen if (!file_in || !file_out) {
26123ba6841SJoseph Chen usage(argv[0]);
26223ba6841SJoseph Chen exit(EXIT_FAILURE);
26323ba6841SJoseph Chen }
26423ba6841SJoseph Chen
26523ba6841SJoseph Chen /* file in */
26623ba6841SJoseph Chen fi = fopen(file_in, "rb");
26723ba6841SJoseph Chen if (!fi) {
26823ba6841SJoseph Chen perror(file_in);
26923ba6841SJoseph Chen exit(EXIT_FAILURE);
27023ba6841SJoseph Chen }
27123ba6841SJoseph Chen
27223ba6841SJoseph Chen /* file out */
27323ba6841SJoseph Chen fo = fopen(file_out, "wb");
27423ba6841SJoseph Chen if (!fo) {
27523ba6841SJoseph Chen perror(file_out);
27623ba6841SJoseph Chen exit(EXIT_FAILURE);
27723ba6841SJoseph Chen }
27823ba6841SJoseph Chen
27923ba6841SJoseph Chen printf("pack input %s \n", file_in);
28023ba6841SJoseph Chen fseek(fi, 0, SEEK_END);
28123ba6841SJoseph Chen size = ftell(fi);
28223ba6841SJoseph Chen fseek(fi, 0, SEEK_SET);
2832bbbd780SJoseph Chen printf("pack file size: %d(%d KB)\n", size, size / 1024);
28423ba6841SJoseph Chen if (size > max_size - sizeof(second_loader_hdr)) {
28523ba6841SJoseph Chen perror(file_out);
28623ba6841SJoseph Chen exit(EXIT_FAILURE);
28723ba6841SJoseph Chen }
28823ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr));
28923ba6841SJoseph Chen memcpy((char *)hdr.magic, magic, LOADER_MAGIC_SIZE);
29023ba6841SJoseph Chen hdr.version = curr_version;
29123ba6841SJoseph Chen hdr.loader_load_addr = loader_addr;
29223ba6841SJoseph Chen if (!fread(buf + sizeof(second_loader_hdr), size, 1, fi))
29323ba6841SJoseph Chen exit(EXIT_FAILURE);
29423ba6841SJoseph Chen
29523ba6841SJoseph Chen /* Aligned size to 4-byte, Rockchip HW Crypto need 4-byte align */
29623ba6841SJoseph Chen size = (((size + 3) >> 2) << 2);
29723ba6841SJoseph Chen hdr.loader_load_size = size;
29823ba6841SJoseph Chen
29923ba6841SJoseph Chen hdr.crc32 = crc32_rk(
30023ba6841SJoseph Chen 0, (const unsigned char *)buf + sizeof(second_loader_hdr), size);
30123ba6841SJoseph Chen printf("crc = 0x%08x\n", hdr.crc32);
302*c64e2562SYifeng Zhao hdr.js_hash = js_hash((uint8_t *)buf + sizeof(second_loader_hdr), size);
30323ba6841SJoseph Chen #ifndef CONFIG_SECUREBOOT_SHA256
30423ba6841SJoseph Chen SHA_CTX ctx;
30523ba6841SJoseph Chen uint8_t *sha;
30623ba6841SJoseph Chen hdr.hash_len = (SHA_DIGEST_SIZE > LOADER_HASH_SIZE) ? LOADER_HASH_SIZE
30723ba6841SJoseph Chen : SHA_DIGEST_SIZE;
30823ba6841SJoseph Chen SHA_init(&ctx);
30923ba6841SJoseph Chen SHA_update(&ctx, buf + sizeof(second_loader_hdr), size);
31023ba6841SJoseph Chen if (hdr.version > 0)
31123ba6841SJoseph Chen SHA_update(&ctx, (void *)&hdr.version, 8);
31223ba6841SJoseph Chen
31323ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_addr, sizeof(hdr.loader_load_addr));
31423ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_size, sizeof(hdr.loader_load_size));
31523ba6841SJoseph Chen SHA_update(&ctx, &hdr.hash_len, sizeof(hdr.hash_len));
31623ba6841SJoseph Chen sha = (uint8_t *)SHA_final(&ctx);
31723ba6841SJoseph Chen memcpy(hdr.hash, sha, hdr.hash_len);
31823ba6841SJoseph Chen #else
31923ba6841SJoseph Chen sha256_context ctx;
32023ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE];
32123ba6841SJoseph Chen
32223ba6841SJoseph Chen memset(hash, 0, LOADER_HASH_SIZE);
32323ba6841SJoseph Chen
32423ba6841SJoseph Chen hdr.hash_len = 32; /* sha256 */
32523ba6841SJoseph Chen sha256_starts(&ctx);
32623ba6841SJoseph Chen sha256_update(&ctx, (void *)buf + sizeof(second_loader_hdr), size);
32723ba6841SJoseph Chen if (hdr.version > 0)
32823ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.version, 8);
32923ba6841SJoseph Chen
33023ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_addr,
33123ba6841SJoseph Chen sizeof(hdr.loader_load_addr));
33223ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_size,
33323ba6841SJoseph Chen sizeof(hdr.loader_load_size));
33423ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.hash_len, sizeof(hdr.hash_len));
33523ba6841SJoseph Chen sha256_finish(&ctx, hash);
33623ba6841SJoseph Chen memcpy(hdr.hash, hash, hdr.hash_len);
33723ba6841SJoseph Chen #endif /* CONFIG_SECUREBOOT_SHA256 */
33823ba6841SJoseph Chen
33923ba6841SJoseph Chen printf("%s version: %s\n", name, version);
34023ba6841SJoseph Chen memcpy(buf, &hdr, sizeof(second_loader_hdr));
341*c64e2562SYifeng Zhao if (image == IMAGE_KERNEL)
342*c64e2562SYifeng Zhao fwrite(buf, size + sizeof(second_loader_hdr), 1, fo);
343*c64e2562SYifeng Zhao else
34423ba6841SJoseph Chen for (i = 0; i < max_num; i++)
34523ba6841SJoseph Chen fwrite(buf, max_size, 1, fo);
34623ba6841SJoseph Chen
34723ba6841SJoseph Chen printf("pack %s success! \n", file_out);
34823ba6841SJoseph Chen fclose(fi);
34923ba6841SJoseph Chen fclose(fo);
35023ba6841SJoseph Chen } else if (mode == MODE_UNPACK) {
35123ba6841SJoseph Chen buf = calloc(max_size, max_num);
35223ba6841SJoseph Chen if (!buf) {
35323ba6841SJoseph Chen perror(file_out);
35423ba6841SJoseph Chen exit(EXIT_FAILURE);
35523ba6841SJoseph Chen }
35623ba6841SJoseph Chen if (!file_in || !file_out) {
35723ba6841SJoseph Chen usage(argv[0]);
35823ba6841SJoseph Chen exit(EXIT_FAILURE);
35923ba6841SJoseph Chen }
36023ba6841SJoseph Chen
36123ba6841SJoseph Chen /* file in */
36223ba6841SJoseph Chen fi = fopen(file_in, "rb");
36323ba6841SJoseph Chen if (!fi) {
36423ba6841SJoseph Chen perror(file_in);
36523ba6841SJoseph Chen exit(EXIT_FAILURE);
36623ba6841SJoseph Chen }
36723ba6841SJoseph Chen
36823ba6841SJoseph Chen /* file out */
36923ba6841SJoseph Chen fo = fopen(file_out, "wb");
37023ba6841SJoseph Chen if (!fo) {
37123ba6841SJoseph Chen perror(file_out);
37223ba6841SJoseph Chen exit(EXIT_FAILURE);
37323ba6841SJoseph Chen }
37423ba6841SJoseph Chen
37523ba6841SJoseph Chen printf("unpack input %s \n", file_in);
37623ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr));
37723ba6841SJoseph Chen if (!fread(&hdr, sizeof(second_loader_hdr), 1, fi))
37823ba6841SJoseph Chen exit(EXIT_FAILURE);
37923ba6841SJoseph Chen
38023ba6841SJoseph Chen if (!fread(buf, hdr.loader_load_size, 1, fi))
38123ba6841SJoseph Chen exit(EXIT_FAILURE);
38223ba6841SJoseph Chen
38323ba6841SJoseph Chen fwrite(buf, hdr.loader_load_size, 1, fo);
38423ba6841SJoseph Chen printf("unpack %s success! \n", file_out);
38523ba6841SJoseph Chen fclose(fi);
38623ba6841SJoseph Chen fclose(fo);
38723ba6841SJoseph Chen } else if (mode == MODE_INFO) {
38823ba6841SJoseph Chen second_loader_hdr *hdr;
38923ba6841SJoseph Chen
39023ba6841SJoseph Chen hdr = malloc(sizeof(struct tag_second_loader_hdr));
39123ba6841SJoseph Chen if (hdr == NULL) {
39223ba6841SJoseph Chen printf("Memory error!\n");
39323ba6841SJoseph Chen exit(EXIT_FAILURE);
39423ba6841SJoseph Chen }
39523ba6841SJoseph Chen /* file in */
39623ba6841SJoseph Chen fi = fopen(file_in, "rb");
39723ba6841SJoseph Chen if (!fi) {
39823ba6841SJoseph Chen perror(file_in);
39923ba6841SJoseph Chen exit(EXIT_FAILURE);
40023ba6841SJoseph Chen }
40123ba6841SJoseph Chen
40223ba6841SJoseph Chen if (!fread(hdr, sizeof(struct tag_second_loader_hdr), 1, fi))
40323ba6841SJoseph Chen exit(EXIT_FAILURE);
40423ba6841SJoseph Chen
40523ba6841SJoseph Chen if (!(memcmp(RK_UBOOT_MAGIC, hdr->magic, 5)) ||
40623ba6841SJoseph Chen !(memcmp(RK_TRUST_MAGIC, hdr->magic, 3))) {
40723ba6841SJoseph Chen printf("The image info:\n");
40823ba6841SJoseph Chen printf("Rollback index is %d\n", hdr->version);
40923ba6841SJoseph Chen printf("Load Addr is 0x%x\n", hdr->loader_load_addr);
41023ba6841SJoseph Chen } else {
41123ba6841SJoseph Chen printf("Please input the correct file.\n");
41223ba6841SJoseph Chen }
41323ba6841SJoseph Chen
41423ba6841SJoseph Chen fclose(fi);
41523ba6841SJoseph Chen free(hdr);
41623ba6841SJoseph Chen }
41723ba6841SJoseph Chen free(buf);
41823ba6841SJoseph Chen
41923ba6841SJoseph Chen return 0;
42023ba6841SJoseph Chen }
421