2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License,
4 * version 2 as published by the Free Software Foundation.
6 * (C) Nicolò Veronese <nicveronese@gmail.com>
19 #include <netinet/in.h> // htonl
21 // Usage: mkdapimg2 -s signature [-v version] [-r region]
22 // [-k uImage block size] -i <input> -o <output>
24 // NOTE: The kernel block size is used to know the offset of the rootfs
27 // The system writes in the uImage partition until the end of uImage
28 // is reached, after that, the system jumps to the offset specified with the -k
29 // parameter and begin writing at the beginning of the rootfs MTD partition.
31 // If the -k parameter is the size of the original uImage partition, the system
32 // continue writing in the rootfs partition starting from the last block
33 // that has been wrote. (This is useful if the new kernel size is
34 // different from the original one)
37 // ------------------------------------------
38 // Creating 7 MTD partitions on "ath-nor0":
39 // 0x000000000000-0x000000010000 : "u-boot"
40 // 0x000000010000-0x000000020000 : "ART"
41 // 0x000000020000-0x000000030000 : "MP"
42 // 0x000000030000-0x000000040000 : "config"
43 // 0x000000040000-0x000000120000 : "uImage"
44 // 0x000000120000-0x000000800000 : "rootfs"
45 // 0x000000040000-0x000000800000 : "firmware"
46 // ------------------------------------------
48 // 0x000000120000-0x000000040000 = 0xE0000 -> 917504
50 // e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default
51 // -k 917504 -i sysupgarde.bin -o factory.bin
54 // The img_hdr_struct was taken from the D-Link SDK:
55 // DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch
57 #define MAX_SIGN_LEN 32
58 #define MAX_FW_VER_LEN 16
61 struct img_hdr_struct
{
66 char signature
[MAX_SIGN_LEN
];
67 char fw_ver
[MAX_FW_VER_LEN
];
68 char fw_reg
[MAX_REG_LEN
];
74 perrexit(int code
, char *msg
)
76 fprintf(stderr
, "%s: %s: %s\n", progname
, msg
, strerror(errno
));
83 fprintf(stderr
, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname
);
88 main(int ac
, char *av
[])
90 char signature
[MAX_SIGN_LEN
];
91 char version
[MAX_FW_VER_LEN
];
92 char region
[MAX_REG_LEN
];
101 progname
= basename(av
[0]);
103 memset(signature
, 0, sizeof(signature
));
104 memset(version
, 0, sizeof(version
));
105 memset(region
, 0, sizeof(region
));
111 c
= getopt(ac
, av
, "s:v:r:k:i:o:");
117 if (strlen(optarg
) > MAX_SIGN_LEN
+ 1) {
118 fprintf(stderr
, "%s: signature exceeds %d chars\n",
119 progname
, MAX_SIGN_LEN
);
122 strcpy(signature
, optarg
);
125 if (strlen(optarg
) > MAX_FW_VER_LEN
+ 1) {
126 fprintf(stderr
, "%s: version exceeds %d chars\n",
127 progname
, MAX_FW_VER_LEN
);
130 strcpy(version
, optarg
);
133 if (strlen(optarg
) > MAX_REG_LEN
+ 1) {
134 fprintf(stderr
, "%s: region exceeds %d chars\n",
135 progname
, MAX_REG_LEN
);
138 strcpy(region
, optarg
);
141 kernel
= strtoul(optarg
, &ptr
, 0);
147 if ((ifile
= fopen(optarg
, "r")) == NULL
)
151 if ((ofile
= fopen(optarg
, "w")) == NULL
)
159 if (signature
[0] == 0 || ifile
== NULL
|| ofile
== NULL
) {
164 for (bcnt
= 0, cksum
= 0 ; (c
= fgetc(ifile
)) != EOF
; bcnt
++)
167 if (fseek(ifile
, 0, SEEK_SET
) < 0)
168 perrexit(2, "fseek on input");
170 // Fill in the header
171 memset(&imghdr
, 0, sizeof(imghdr
));
172 imghdr
.hdr_len
= sizeof(imghdr
);
173 imghdr
.checksum
= htonl(cksum
);
174 imghdr
.total_size
= htonl(bcnt
);
175 imghdr
.kernel_size
= htonl(kernel
);
177 strncpy(imghdr
.signature
, signature
, MAX_SIGN_LEN
);
178 strncpy(imghdr
.fw_ver
, version
, MAX_FW_VER_LEN
);
179 strncpy(imghdr
.fw_reg
, region
, MAX_REG_LEN
);
181 if (fwrite(&imghdr
, sizeof(imghdr
), 1, ofile
) < 0)
182 perrexit(2, "fwrite header on output");
184 while ((c
= fgetc(ifile
)) != EOF
) {
185 if (fputc(c
, ofile
) == EOF
)
186 perrexit(2, "fputc on output");
190 perrexit(2, "fgetc on input");
195 fprintf(stderr
, "imgHdr.hdr_len = %lu\n", sizeof(imghdr
));
196 fprintf(stderr
, "imgHdr.checksum = 0x%08x\n", cksum
);
197 fprintf(stderr
, "imgHdr.total_size = 0x%08x\n", bcnt
);
198 fprintf(stderr
, "imgHdr.kernel_size = 0x%08x\n", kernel
);
199 fprintf(stderr
, "imgHdr.header = %s\n", signature
);
200 fprintf(stderr
, "imgHdr.fw_ver = %s\n", version
);
201 fprintf(stderr
, "imgHdr.fw_reg = %s\n", region
);