ramips: add support for Fon FON2601
[oweals/openwrt.git] / tools / firmware-utils / src / uimage_padhdr.c
1 /*
2  * uimage_padhdr.c : add zero paddings after the tail of uimage header
3  *
4  * Copyright (C) 2019 NOGUCHI Hiroshi <drvlabo@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License,
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  */
15
16 #include <stdio.h>
17 #include <errno.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <arpa/inet.h>
24 #include <zlib.h>
25
26
27 /* from u-boot/include/image.h */
28 #define IH_MAGIC        0x27051956      /* Image Magic Number           */
29 #define IH_NMLEN                32      /* Image Name Length            */
30
31 /*
32  * Legacy format image header,
33  * all data in network byte order (aka natural aka bigendian).
34  */
35 typedef struct image_header {
36         uint32_t        ih_magic;       /* Image Header Magic Number    */
37         uint32_t        ih_hcrc;        /* Image Header CRC Checksum    */
38         uint32_t        ih_time;        /* Image Creation Timestamp     */
39         uint32_t        ih_size;        /* Image Data Size              */
40         uint32_t        ih_load;        /* Data  Load  Address          */
41         uint32_t        ih_ep;          /* Entry Point Address          */
42         uint32_t        ih_dcrc;        /* Image Data CRC Checksum      */
43         uint8_t         ih_os;          /* Operating System             */
44         uint8_t         ih_arch;        /* CPU architecture             */
45         uint8_t         ih_type;        /* Image Type                   */
46         uint8_t         ih_comp;        /* Compression Type             */
47         uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
48 } image_header_t;
49
50
51 /* default padding size */
52 #define IH_PAD_BYTES            (32)
53
54
55 static void usage(char *prog)
56 {
57         fprintf(stderr,
58                 "%s -i <input_uimage_file> -o <output_file> [-l <padding bytes>]\n",
59                 prog);
60 }
61
62 int main(int argc, char *argv[])
63 {
64         struct stat statbuf;
65         u_int8_t *filebuf;
66         int ifd;
67         int ofd;
68         ssize_t rsz;
69         u_int32_t crc_recalc;
70         image_header_t *imgh;
71         int opt;
72         char *infname = NULL;
73         char *outfname = NULL;
74         int padsz = IH_PAD_BYTES;
75         int ltmp;
76
77         while ((opt = getopt(argc, argv, "i:o:l:")) != -1) {
78                 switch (opt) {
79                 case 'i':
80                         infname = optarg;
81                         break;
82                 case 'o':
83                         outfname = optarg;
84                         break;
85                 case 'l':
86                         ltmp = strtol(optarg, NULL, 0);
87                         if (ltmp > 0)
88                                 padsz = ltmp;
89                         break;
90                 default:
91                         break;
92                 }
93         }
94
95         if (!infname || !outfname) {
96                 usage(argv[0]);
97                 exit(1);
98         }
99
100         if (stat(infname, &statbuf) < 0) {
101                 fprintf(stderr,
102                         "could not find input file. (errno = %d)\n", errno);
103                 exit(1);
104         }
105
106         filebuf = malloc(statbuf.st_size + padsz);
107         if (!filebuf) {
108                 fprintf(stderr, "buffer allocation failed\n");
109                 exit(1);
110         }
111
112         ifd = open(infname, O_RDONLY);
113         if (ifd < 0) {
114                 fprintf(stderr,
115                         "could not open input file. (errno = %d)\n", errno);
116                 exit(1);
117         }
118
119         ofd = open(outfname, O_WRONLY | O_CREAT, 0644);
120         if (ofd < 0) {
121                 fprintf(stderr,
122                         "could not open output file. (errno = %d)\n", errno);
123                 exit(1);
124         }
125
126         rsz = read(ifd, filebuf, sizeof(*imgh));
127         if (rsz != sizeof(*imgh)) {
128                 fprintf(stderr,
129                         "could not read input file (errno = %d).\n", errno);
130                 exit(1);
131         }
132
133         memset(&(filebuf[sizeof(*imgh)]), 0, padsz);
134
135         rsz = read(ifd, &(filebuf[sizeof(*imgh) + padsz]),
136                                 statbuf.st_size - sizeof(*imgh));
137         if (rsz != (int32_t)(statbuf.st_size - sizeof(*imgh))) {
138                 fprintf(stderr,
139                         "could not read input file (errno = %d).\n", errno);
140                 exit(1);
141         }
142
143         imgh = (image_header_t *)filebuf;
144
145         imgh->ih_hcrc = 0;
146         crc_recalc = crc32(0, filebuf, sizeof(*imgh) + padsz);
147         imgh->ih_hcrc = htonl(crc_recalc);
148
149         rsz = write(ofd, filebuf, statbuf.st_size + padsz);
150         if (rsz != (int32_t)statbuf.st_size + padsz) {
151                 fprintf(stderr,
152                         "could not write output file (errnor = %d).\n", errno);
153                 exit(1);
154         }
155
156         return 0;
157 }