• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/mkdapimg2.c

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * (C) Nicolò Veronese <nicveronese@gmail.com>
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdint.h>
  8 #include <stdlib.h>
  9 #include <unistd.h>
 10 #include <libgen.h>
 11 #include <stdarg.h>
 12 #include <getopt.h>
 13 #include <string.h>
 14 #include <errno.h>
 15 
 16 #include <netinet/in.h> // htonl
 17 
 18 // Usage: mkdapimg2 -s signature [-v version] [-r region]
 19 //                  [-k uImage block size] -i <input> -o <output>
 20 //
 21 // NOTE: The kernel block size is used to know the offset of the rootfs
 22 // in the image file.
 23 //
 24 // The system writes in the uImage partition until the end of uImage
 25 // is reached, after that, the system jumps to the offset specified with the -k
 26 // parameter and begin writing at the beginning of the rootfs MTD partition.
 27 //
 28 // If the -k parameter is the size of the original uImage partition, the system
 29 // continue writing in the rootfs partition starting from the last block
 30 // that has been wrote. (This is useful if the new kernel size is
 31 // different from the original one)
 32 //
 33 // Example:
 34 // ------------------------------------------
 35 // Creating 7 MTD partitions on "ath-nor0":
 36 // 0x000000000000-0x000000010000 : "u-boot"
 37 // 0x000000010000-0x000000020000 : "ART"
 38 // 0x000000020000-0x000000030000 : "MP"
 39 // 0x000000030000-0x000000040000 : "config"
 40 // 0x000000040000-0x000000120000 : "uImage"
 41 // 0x000000120000-0x000000800000 : "rootfs"
 42 // 0x000000040000-0x000000800000 : "firmware"
 43 // ------------------------------------------
 44 //
 45 // 0x000000120000-0x000000040000 = 0xE0000 -> 917504
 46 //
 47 // e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default
 48 //                 -k 917504 -i sysupgrade.bin -o factory.bin
 49 //
 50 //
 51 // The img_hdr_struct was taken from the D-Link SDK:
 52 // DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch
 53 
 54 #define MAX_SIGN_LEN    32
 55 #define MAX_FW_VER_LEN  16
 56 #define MAX_REG_LEN     8
 57 
 58 struct img_hdr_struct {
 59         uint32_t hdr_len;
 60         uint32_t checksum;
 61         uint32_t total_size;
 62         uint32_t kernel_size;
 63         char signature[MAX_SIGN_LEN];
 64         char fw_ver[MAX_FW_VER_LEN];
 65         char fw_reg[MAX_REG_LEN];
 66 } imghdr ;
 67 
 68 char *progname;
 69 
 70 void
 71 perrexit(int code, char *msg)
 72 {
 73         fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
 74         exit(code);
 75 }
 76 
 77 void
 78 usage()
 79 {
 80         fprintf(stderr, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname);
 81         exit(1);
 82 }
 83 
 84 int
 85 main(int ac, char *av[])
 86 {
 87         char signature[MAX_SIGN_LEN];
 88         char version[MAX_FW_VER_LEN];
 89         char region[MAX_REG_LEN];
 90         int kernel = 0;
 91 
 92         FILE *ifile = NULL;
 93         FILE *ofile = NULL;
 94         int c;
 95 
 96         uint32_t cksum;
 97         uint32_t bcnt;
 98 
 99         progname = basename(av[0]);
100 
101         memset(signature, 0, sizeof(signature));
102         memset(version, 0, sizeof(version));
103         memset(region, 0, sizeof(region));
104 
105         while ( 1 ) {
106                 char *ptr;
107                 int c;
108 
109                 c = getopt(ac, av, "s:v:r:k:i:o:");
110                 if (c == -1)
111                         break;
112 
113                 switch (c) {
114                 case 's':
115                         if (strlen(optarg) > MAX_SIGN_LEN + 1) {
116                                 fprintf(stderr, "%s: signature exceeds %d chars\n",
117                                         progname, MAX_SIGN_LEN);
118                                 exit(1);
119                         }
120                         strcpy(signature, optarg);
121                         break;
122                 case 'v':
123                         if (strlen(optarg) > MAX_FW_VER_LEN + 1) {
124                                 fprintf(stderr, "%s: version exceeds %d chars\n",
125                                         progname, MAX_FW_VER_LEN);
126                                 exit(1);
127                         }
128                         strcpy(version, optarg);
129                         break;
130                 case 'r':
131                         if (strlen(optarg) > MAX_REG_LEN + 1) {
132                                 fprintf(stderr, "%s: region exceeds %d chars\n",
133                                         progname, MAX_REG_LEN);
134                                 exit(1);
135                         }
136                         strcpy(region, optarg);
137                         break;
138                 case 'k':
139                         kernel = strtoul(optarg, &ptr, 0);
140                         if(ptr[0] == 'k'){
141                                 kernel *= 1000;
142                         }
143                         break;
144                 case 'i':
145                         if ((ifile = fopen(optarg, "r")) == NULL)
146                                 perrexit(1, optarg);
147                         break;
148                 case 'o':
149                         if ((ofile = fopen(optarg, "w")) == NULL)
150                                 perrexit(1, optarg);
151                         break;
152                 default:
153                         usage();
154                 }
155         }
156 
157         if (signature[0] == 0 || ifile == NULL || ofile == NULL) {
158                 usage();
159                 exit(1);
160         }
161 
162         for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++)
163                 cksum += c & 0xff;
164 
165         if (fseek(ifile, 0, SEEK_SET) < 0)
166                 perrexit(2, "fseek on input");
167 
168         // Fill in the header
169         memset(&imghdr, 0, sizeof(imghdr));
170         imghdr.hdr_len = sizeof(imghdr);
171         imghdr.checksum = htonl(cksum);
172         imghdr.total_size = htonl(bcnt);
173         imghdr.kernel_size = htonl(kernel);
174 
175         strncpy(imghdr.signature, signature, MAX_SIGN_LEN);
176         strncpy(imghdr.fw_ver, version, MAX_FW_VER_LEN);
177         strncpy(imghdr.fw_reg, region, MAX_REG_LEN);
178 
179         if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
180                 perrexit(2, "fwrite header on output");
181 
182         while ((c = fgetc(ifile)) != EOF) {
183                 if (fputc(c, ofile) == EOF)
184                         perrexit(2, "fputc on output");
185         }
186 
187         if (ferror(ifile))
188                 perrexit(2, "fgetc on input");
189 
190         fclose(ofile);
191         fclose(ifile);
192 
193         fprintf(stderr, "imgHdr.hdr_len = %lu\n", sizeof(imghdr));
194         fprintf(stderr, "imgHdr.checksum = 0x%08x\n", cksum);
195         fprintf(stderr, "imgHdr.total_size = 0x%08x\n", bcnt);
196         fprintf(stderr, "imgHdr.kernel_size = 0x%08x\n", kernel);
197         fprintf(stderr, "imgHdr.header = %s\n", signature);
198         fprintf(stderr, "imgHdr.fw_ver = %s\n", version);
199         fprintf(stderr, "imgHdr.fw_reg = %s\n", region);
200 
201         return 0;
202 }
203 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt