Wed Jan 1 11:48:36 2020 UTC ()
Avoid mixing signed/unsigned arguments to the ? operator.


(martin)
diff -r1.28 -r1.29 src/usr.bin/mkubootimage/mkubootimage.c

cvs diff -r1.28 -r1.29 src/usr.bin/mkubootimage/mkubootimage.c (switch to unified diff)

--- src/usr.bin/mkubootimage/mkubootimage.c 2020/01/01 10:35:10 1.28
+++ src/usr.bin/mkubootimage/mkubootimage.c 2020/01/01 11:48:36 1.29
@@ -1,612 +1,612 @@ @@ -1,612 +1,612 @@
1/* $NetBSD: mkubootimage.c,v 1.28 2020/01/01 10:35:10 skrll Exp $ */ 1/* $NetBSD: mkubootimage.c,v 1.29 2020/01/01 11:48:36 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products 12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission. 13 * derived from this software without specific prior written permission.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE. 25 * SUCH DAMAGE.
26 */ 26 */
27 27
28#if HAVE_NBTOOL_CONFIG_H 28#if HAVE_NBTOOL_CONFIG_H
29#include "nbtool_config.h" 29#include "nbtool_config.h"
30#endif 30#endif
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: mkubootimage.c,v 1.28 2020/01/01 10:35:10 skrll Exp $"); 33__RCSID("$NetBSD: mkubootimage.c,v 1.29 2020/01/01 11:48:36 martin Exp $");
34 34
35#include <sys/mman.h> 35#include <sys/mman.h>
36#include <sys/stat.h> 36#include <sys/stat.h>
37#include <sys/endian.h> 37#include <sys/endian.h>
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/uio.h> 39#include <sys/uio.h>
40#include <err.h> 40#include <err.h>
41#include <errno.h> 41#include <errno.h>
42#include <fcntl.h> 42#include <fcntl.h>
43#include <inttypes.h> 43#include <inttypes.h>
44#include <limits.h> 44#include <limits.h>
45#include <stdint.h> 45#include <stdint.h>
46#include <stdio.h> 46#include <stdio.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49#include <time.h> 49#include <time.h>
50#include <unistd.h> 50#include <unistd.h>
51 51
52#include "uboot.h" 52#include "uboot.h"
53#include "arm64.h" 53#include "arm64.h"
54 54
55#ifndef __arraycount 55#ifndef __arraycount
56#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) 56#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
57#endif 57#endif
58 58
59enum image_format { 59enum image_format {
60 FMT_UNKNOWN, 60 FMT_UNKNOWN,
61 FMT_UIMG, /* Legacy U-Boot image */ 61 FMT_UIMG, /* Legacy U-Boot image */
62 FMT_ARM64, /* Linux ARM64 image (booti) */ 62 FMT_ARM64, /* Linux ARM64 image (booti) */
63}; 63};
64 64
65extern uint32_t crc32(const void *, size_t); 65extern uint32_t crc32(const void *, size_t);
66extern uint32_t crc32v(const struct iovec *, int); 66extern uint32_t crc32v(const struct iovec *, int);
67 67
68static enum uboot_image_os image_os = IH_OS_NETBSD; 68static enum uboot_image_os image_os = IH_OS_NETBSD;
69static enum uboot_image_arch image_arch = IH_ARCH_UNKNOWN; 69static enum uboot_image_arch image_arch = IH_ARCH_UNKNOWN;
70static enum uboot_image_type image_type = IH_TYPE_UNKNOWN; 70static enum uboot_image_type image_type = IH_TYPE_UNKNOWN;
71static enum uboot_image_comp image_comp = IH_COMP_NONE; 71static enum uboot_image_comp image_comp = IH_COMP_NONE;
72static uint32_t image_loadaddr = 0; 72static uint32_t image_loadaddr = 0;
73static uint32_t image_entrypoint = 0; 73static uint32_t image_entrypoint = 0;
74static char *image_name; 74static char *image_name;
75static uint32_t image_magic = IH_MAGIC; 75static uint32_t image_magic = IH_MAGIC;
76static enum image_format image_format = FMT_UIMG; 76static enum image_format image_format = FMT_UIMG;
77static int update_image = 0; 77static int update_image = 0;
78 78
79static const struct uboot_image_format { 79static const struct uboot_image_format {
80 enum image_format format; 80 enum image_format format;
81 const char *name; 81 const char *name;
82} uboot_image_format[] = { 82} uboot_image_format[] = {
83 { FMT_UIMG, "uimg" }, 83 { FMT_UIMG, "uimg" },
84 { FMT_ARM64, "arm64" }, 84 { FMT_ARM64, "arm64" },
85}; 85};
86 86
87static enum image_format 87static enum image_format
88get_image_format(const char *name) 88get_image_format(const char *name)
89{ 89{
90 unsigned int i; 90 unsigned int i;
91 91
92 for (i = 0; i < __arraycount(uboot_image_format); i++) { 92 for (i = 0; i < __arraycount(uboot_image_format); i++) {
93 if (strcmp(uboot_image_format[i].name, name) == 0) 93 if (strcmp(uboot_image_format[i].name, name) == 0)
94 return uboot_image_format[i].format; 94 return uboot_image_format[i].format;
95 } 95 }
96 96
97 return FMT_UNKNOWN; 97 return FMT_UNKNOWN;
98} 98}
99 99
100static const char * 100static const char *
101get_image_format_name(enum image_format format) 101get_image_format_name(enum image_format format)
102{ 102{
103 unsigned int i; 103 unsigned int i;
104 104
105 for (i = 0; i < __arraycount(uboot_image_format); i++) { 105 for (i = 0; i < __arraycount(uboot_image_format); i++) {
106 if (uboot_image_format[i].format == format) 106 if (uboot_image_format[i].format == format)
107 return uboot_image_format[i].name; 107 return uboot_image_format[i].name;
108 } 108 }
109 109
110 return "Unknown"; 110 return "Unknown";
111} 111}
112 112
113static const struct uboot_os { 113static const struct uboot_os {
114 enum uboot_image_os os; 114 enum uboot_image_os os;
115 const char *name; 115 const char *name;
116} uboot_os[] = { 116} uboot_os[] = {
117 { IH_OS_OPENBSD, "openbsd" }, 117 { IH_OS_OPENBSD, "openbsd" },
118 { IH_OS_NETBSD, "netbsd" }, 118 { IH_OS_NETBSD, "netbsd" },
119 { IH_OS_FREEBSD, "freebsd" }, 119 { IH_OS_FREEBSD, "freebsd" },
120 { IH_OS_LINUX, "linux" }, 120 { IH_OS_LINUX, "linux" },
121}; 121};
122 122
123static enum uboot_image_os 123static enum uboot_image_os
124get_os(const char *name) 124get_os(const char *name)
125{ 125{
126 unsigned int i; 126 unsigned int i;
127 127
128 for (i = 0; i < __arraycount(uboot_os); i++) { 128 for (i = 0; i < __arraycount(uboot_os); i++) {
129 if (strcmp(uboot_os[i].name, name) == 0) 129 if (strcmp(uboot_os[i].name, name) == 0)
130 return uboot_os[i].os; 130 return uboot_os[i].os;
131 } 131 }
132 132
133 return IH_OS_UNKNOWN; 133 return IH_OS_UNKNOWN;
134} 134}
135 135
136static const char * 136static const char *
137get_os_name(enum uboot_image_os os) 137get_os_name(enum uboot_image_os os)
138{ 138{
139 unsigned int i; 139 unsigned int i;
140 140
141 for (i = 0; i < __arraycount(uboot_os); i++) { 141 for (i = 0; i < __arraycount(uboot_os); i++) {
142 if (uboot_os[i].os == os) 142 if (uboot_os[i].os == os)
143 return uboot_os[i].name; 143 return uboot_os[i].name;
144 } 144 }
145 145
146 return "Unknown"; 146 return "Unknown";
147} 147}
148 148
149static const struct uboot_arch { 149static const struct uboot_arch {
150 enum uboot_image_arch arch; 150 enum uboot_image_arch arch;
151 const char *name; 151 const char *name;
152} uboot_arch[] = { 152} uboot_arch[] = {
153 { IH_ARCH_ARM, "arm" }, 153 { IH_ARCH_ARM, "arm" },
154 { IH_ARCH_ARM64, "arm64" }, 154 { IH_ARCH_ARM64, "arm64" },
155 { IH_ARCH_I386, "i386" }, 155 { IH_ARCH_I386, "i386" },
156 { IH_ARCH_MIPS, "mips" }, 156 { IH_ARCH_MIPS, "mips" },
157 { IH_ARCH_MIPS64, "mips64" }, 157 { IH_ARCH_MIPS64, "mips64" },
158 { IH_ARCH_PPC, "powerpc" }, 158 { IH_ARCH_PPC, "powerpc" },
159 { IH_ARCH_OPENRISC, "or1k" }, 159 { IH_ARCH_OPENRISC, "or1k" },
160 { IH_ARCH_SH, "sh" }, 160 { IH_ARCH_SH, "sh" },
161}; 161};
162 162
163static enum uboot_image_arch 163static enum uboot_image_arch
164get_arch(const char *name) 164get_arch(const char *name)
165{ 165{
166 unsigned int i; 166 unsigned int i;
167 167
168 for (i = 0; i < __arraycount(uboot_arch); i++) { 168 for (i = 0; i < __arraycount(uboot_arch); i++) {
169 if (strcmp(uboot_arch[i].name, name) == 0) 169 if (strcmp(uboot_arch[i].name, name) == 0)
170 return uboot_arch[i].arch; 170 return uboot_arch[i].arch;
171 } 171 }
172 172
173 return IH_ARCH_UNKNOWN; 173 return IH_ARCH_UNKNOWN;
174} 174}
175 175
176static const char *  176static const char *
177get_arch_name(enum uboot_image_arch arch) 177get_arch_name(enum uboot_image_arch arch)
178{ 178{
179 unsigned int i; 179 unsigned int i;
180 180
181 for (i = 0; i < __arraycount(uboot_arch); i++) { 181 for (i = 0; i < __arraycount(uboot_arch); i++) {
182 if (uboot_arch[i].arch == arch) 182 if (uboot_arch[i].arch == arch)
183 return uboot_arch[i].name; 183 return uboot_arch[i].name;
184 } 184 }
185 185
186 return "Unknown"; 186 return "Unknown";
187} 187}
188 188
189static const struct uboot_type { 189static const struct uboot_type {
190 enum uboot_image_type type; 190 enum uboot_image_type type;
191 const char *name; 191 const char *name;
192} uboot_type[] = { 192} uboot_type[] = {
193 { IH_TYPE_STANDALONE, "standalone" }, 193 { IH_TYPE_STANDALONE, "standalone" },
194 { IH_TYPE_KERNEL, "kernel" }, 194 { IH_TYPE_KERNEL, "kernel" },
195 { IH_TYPE_KERNEL_NOLOAD, "kernel_noload" }, 195 { IH_TYPE_KERNEL_NOLOAD, "kernel_noload" },
196 { IH_TYPE_RAMDISK, "ramdisk" }, 196 { IH_TYPE_RAMDISK, "ramdisk" },
197 { IH_TYPE_FILESYSTEM, "fs" }, 197 { IH_TYPE_FILESYSTEM, "fs" },
198 { IH_TYPE_SCRIPT, "script" }, 198 { IH_TYPE_SCRIPT, "script" },
199}; 199};
200 200
201static enum uboot_image_type 201static enum uboot_image_type
202get_type(const char *name) 202get_type(const char *name)
203{ 203{
204 unsigned int i; 204 unsigned int i;
205 205
206 for (i = 0; i < __arraycount(uboot_type); i++) { 206 for (i = 0; i < __arraycount(uboot_type); i++) {
207 if (strcmp(uboot_type[i].name, name) == 0) 207 if (strcmp(uboot_type[i].name, name) == 0)
208 return uboot_type[i].type; 208 return uboot_type[i].type;
209 } 209 }
210 210
211 return IH_TYPE_UNKNOWN; 211 return IH_TYPE_UNKNOWN;
212} 212}
213 213
214static const char * 214static const char *
215get_type_name(enum uboot_image_type type) 215get_type_name(enum uboot_image_type type)
216{ 216{
217 unsigned int i; 217 unsigned int i;
218 218
219 for (i = 0; i < __arraycount(uboot_type); i++) { 219 for (i = 0; i < __arraycount(uboot_type); i++) {
220 if (uboot_type[i].type == type) 220 if (uboot_type[i].type == type)
221 return uboot_type[i].name; 221 return uboot_type[i].name;
222 } 222 }
223 223
224 return "Unknown"; 224 return "Unknown";
225} 225}
226 226
227static const struct uboot_comp { 227static const struct uboot_comp {
228 enum uboot_image_comp comp; 228 enum uboot_image_comp comp;
229 const char *name; 229 const char *name;
230} uboot_comp[] = { 230} uboot_comp[] = {
231 { IH_COMP_NONE, "none" }, 231 { IH_COMP_NONE, "none" },
232 { IH_COMP_GZIP, "gz" }, 232 { IH_COMP_GZIP, "gz" },
233 { IH_COMP_BZIP2, "bz2" }, 233 { IH_COMP_BZIP2, "bz2" },
234 { IH_COMP_LZMA, "lzma" }, 234 { IH_COMP_LZMA, "lzma" },
235 { IH_COMP_LZO, "lzo" }, 235 { IH_COMP_LZO, "lzo" },
236}; 236};
237 237
238static enum uboot_image_comp 238static enum uboot_image_comp
239get_comp(const char *name) 239get_comp(const char *name)
240{ 240{
241 unsigned int i; 241 unsigned int i;
242 242
243 for (i = 0; i < __arraycount(uboot_comp); i++) { 243 for (i = 0; i < __arraycount(uboot_comp); i++) {
244 if (strcmp(uboot_comp[i].name, name) == 0) 244 if (strcmp(uboot_comp[i].name, name) == 0)
245 return uboot_comp[i].comp; 245 return uboot_comp[i].comp;
246 } 246 }
247 247
248 return IH_COMP_NONE; 248 return IH_COMP_NONE;
249} 249}
250 250
251static const char * 251static const char *
252get_comp_name(enum uboot_image_comp comp) 252get_comp_name(enum uboot_image_comp comp)
253{ 253{
254 unsigned int i; 254 unsigned int i;
255 255
256 for (i = 0; i < __arraycount(uboot_comp); i++) { 256 for (i = 0; i < __arraycount(uboot_comp); i++) {
257 if (uboot_comp[i].comp == comp) 257 if (uboot_comp[i].comp == comp)
258 return uboot_comp[i].name; 258 return uboot_comp[i].name;
259 } 259 }
260 260
261 return "Unknown"; 261 return "Unknown";
262} 262}
263 263
264__dead static void 264__dead static void
265usage(void) 265usage(void)
266{ 266{
267 fprintf(stderr, "usage: mkubootimage [-hu] -A " 267 fprintf(stderr, "usage: mkubootimage [-hu] -A "
268 "<arm|arm64|i386|mips|mips64|or1k|powerpc|sh> -a address\n"); 268 "<arm|arm64|i386|mips|mips64|or1k|powerpc|sh> -a address\n");
269 fprintf(stderr, "\t-C <bz2|gz|lzma|lzo|none> [-E address] [-e address]\n"); 269 fprintf(stderr, "\t-C <bz2|gz|lzma|lzo|none> [-E address] [-e address]\n");
270 fprintf(stderr, "\t[-f <arm64|uimg>] [-m magic] -n image -O <freebsd|linux|netbsd|openbsd>\n"); 270 fprintf(stderr, "\t[-f <arm64|uimg>] [-m magic] -n image -O <freebsd|linux|netbsd|openbsd>\n");
271 fprintf(stderr, "\t-T <fs|kernel|kernel_noload|ramdisk|script|standalone>\n"); 271 fprintf(stderr, "\t-T <fs|kernel|kernel_noload|ramdisk|script|standalone>\n");
272 fprintf(stderr, "\tsource destination\n"); 272 fprintf(stderr, "\tsource destination\n");
273 273
274 exit(EXIT_FAILURE); 274 exit(EXIT_FAILURE);
275} 275}
276 276
277static void 277static void
278dump_header_uimg(struct uboot_image_header *hdr) 278dump_header_uimg(struct uboot_image_header *hdr)
279{ 279{
280 time_t tm = ntohl(hdr->ih_time); 280 time_t tm = ntohl(hdr->ih_time);
281 281
282 printf(" magic: 0x%08x\n", ntohl(hdr->ih_magic)); 282 printf(" magic: 0x%08x\n", ntohl(hdr->ih_magic));
283 printf(" time: %s", ctime(&tm)); 283 printf(" time: %s", ctime(&tm));
284 printf(" size: %u\n", ntohl(hdr->ih_size)); 284 printf(" size: %u\n", ntohl(hdr->ih_size));
285 printf(" load addr: 0x%08x\n", ntohl(hdr->ih_load)); 285 printf(" load addr: 0x%08x\n", ntohl(hdr->ih_load));
286 printf(" entry point: 0x%08x\n", ntohl(hdr->ih_ep)); 286 printf(" entry point: 0x%08x\n", ntohl(hdr->ih_ep));
287 printf(" data crc: 0x%08x\n", ntohl(hdr->ih_dcrc)); 287 printf(" data crc: 0x%08x\n", ntohl(hdr->ih_dcrc));
288 printf(" os: %d (%s)\n", hdr->ih_os, 288 printf(" os: %d (%s)\n", hdr->ih_os,
289 get_os_name(hdr->ih_os)); 289 get_os_name(hdr->ih_os));
290 printf(" arch: %d (%s)\n", hdr->ih_arch, 290 printf(" arch: %d (%s)\n", hdr->ih_arch,
291 get_arch_name(hdr->ih_arch)); 291 get_arch_name(hdr->ih_arch));
292 printf(" type: %d (%s)\n", hdr->ih_type, 292 printf(" type: %d (%s)\n", hdr->ih_type,
293 get_type_name(hdr->ih_type)); 293 get_type_name(hdr->ih_type));
294 printf(" comp: %d (%s)\n", hdr->ih_comp, 294 printf(" comp: %d (%s)\n", hdr->ih_comp,
295 get_comp_name(hdr->ih_comp)); 295 get_comp_name(hdr->ih_comp));
296 printf(" name: %s\n", hdr->ih_name); 296 printf(" name: %s\n", hdr->ih_name);
297 printf(" header crc: 0x%08x\n", hdr->ih_hcrc); 297 printf(" header crc: 0x%08x\n", hdr->ih_hcrc);
298} 298}
299 299
300static int 300static int
301generate_header_uimg(struct uboot_image_header *hdr, int kernel_fd) 301generate_header_uimg(struct uboot_image_header *hdr, int kernel_fd)
302{ 302{
303 uint8_t *p; 303 uint8_t *p;
304 struct stat st; 304 struct stat st;
305 uint32_t crc, dsize, size_buf[2]; 305 uint32_t crc, dsize, size_buf[2];
306 int error; 306 int error;
307 307
308 error = fstat(kernel_fd, &st); 308 error = fstat(kernel_fd, &st);
309 if (error == -1) { 309 if (error == -1) {
310 perror("stat"); 310 perror("stat");
311 return errno; 311 return errno;
312 } 312 }
313 313
314 if (st.st_size + sizeof(*hdr) > UINT32_MAX) { 314 if (st.st_size + sizeof(*hdr) > UINT32_MAX) {
315 fprintf(stderr, "fatal: kernel too big\n"); 315 fprintf(stderr, "fatal: kernel too big\n");
316 return EINVAL; 316 return EINVAL;
317 } 317 }
318 318
319 p = mmap(0, st.st_size, PROT_READ, MAP_FILE|MAP_SHARED, kernel_fd, 0); 319 p = mmap(0, st.st_size, PROT_READ, MAP_FILE|MAP_SHARED, kernel_fd, 0);
320 if (p == MAP_FAILED) { 320 if (p == MAP_FAILED) {
321 perror("mmap kernel"); 321 perror("mmap kernel");
322 return EINVAL; 322 return EINVAL;
323 } 323 }
324 if (image_type == IH_TYPE_SCRIPT) { 324 if (image_type == IH_TYPE_SCRIPT) {
325 struct iovec iov[3]; 325 struct iovec iov[3];
326 dsize = st.st_size + (sizeof(uint32_t) * 2); 326 dsize = st.st_size + (sizeof(uint32_t) * 2);
327 size_buf[0] = htonl(st.st_size); 327 size_buf[0] = htonl(st.st_size);
328 size_buf[1] = htonl(0); 328 size_buf[1] = htonl(0);
329 iov[0].iov_base = &size_buf[0]; 329 iov[0].iov_base = &size_buf[0];
330 iov[0].iov_len = sizeof(size_buf[0]); 330 iov[0].iov_len = sizeof(size_buf[0]);
331 iov[1].iov_base = &size_buf[1]; 331 iov[1].iov_base = &size_buf[1];
332 iov[1].iov_len = sizeof(size_buf[1]); 332 iov[1].iov_len = sizeof(size_buf[1]);
333 iov[2].iov_base = p; 333 iov[2].iov_base = p;
334 iov[2].iov_len = st.st_size; 334 iov[2].iov_len = st.st_size;
335 crc = crc32v(iov, 3); 335 crc = crc32v(iov, 3);
336 } else { 336 } else {
337 dsize = update_image ? 337 dsize = update_image ?
338 st.st_size - sizeof(*hdr) : st.st_size; 338 (uint32_t)st.st_size - sizeof(*hdr) : (uint32_t)st.st_size;
339 crc = crc32(p, st.st_size); 339 crc = crc32(p, st.st_size);
340 } 340 }
341 munmap(p, st.st_size); 341 munmap(p, st.st_size);
342 342
343 memset(hdr, 0, sizeof(*hdr)); 343 memset(hdr, 0, sizeof(*hdr));
344 hdr->ih_magic = htonl(image_magic); 344 hdr->ih_magic = htonl(image_magic);
345 hdr->ih_time = htonl(st.st_mtime); 345 hdr->ih_time = htonl(st.st_mtime);
346 hdr->ih_size = htonl(dsize); 346 hdr->ih_size = htonl(dsize);
347 hdr->ih_load = htonl(image_loadaddr); 347 hdr->ih_load = htonl(image_loadaddr);
348 hdr->ih_ep = htonl(image_entrypoint); 348 hdr->ih_ep = htonl(image_entrypoint);
349 hdr->ih_dcrc = htonl(crc); 349 hdr->ih_dcrc = htonl(crc);
350 hdr->ih_os = image_os; 350 hdr->ih_os = image_os;
351 hdr->ih_arch = image_arch; 351 hdr->ih_arch = image_arch;
352 hdr->ih_type = image_type; 352 hdr->ih_type = image_type;
353 hdr->ih_comp = image_comp; 353 hdr->ih_comp = image_comp;
354 strlcpy((char *)hdr->ih_name, image_name, sizeof(hdr->ih_name)); 354 strlcpy((char *)hdr->ih_name, image_name, sizeof(hdr->ih_name));
355 crc = crc32((void *)hdr, sizeof(*hdr)); 355 crc = crc32((void *)hdr, sizeof(*hdr));
356 hdr->ih_hcrc = htonl(crc); 356 hdr->ih_hcrc = htonl(crc);
357 357
358 dump_header_uimg(hdr); 358 dump_header_uimg(hdr);
359 359
360 return 0; 360 return 0;
361} 361}
362 362
363static void 363static void
364dump_header_arm64(struct arm64_image_header *hdr) 364dump_header_arm64(struct arm64_image_header *hdr)
365{ 365{
366 printf(" magic: 0x%" PRIx32 "\n", le32toh(hdr->magic)); 366 printf(" magic: 0x%" PRIx32 "\n", le32toh(hdr->magic));
367 printf(" text offset: 0x%" PRIx64 "\n", le64toh(hdr->text_offset)); 367 printf(" text offset: 0x%" PRIx64 "\n", le64toh(hdr->text_offset));
368 printf(" image size: %" PRIu64 "\n", le64toh(hdr->image_size)); 368 printf(" image size: %" PRIu64 "\n", le64toh(hdr->image_size));
369 printf(" flags: 0x%" PRIx64 "\n", le64toh(hdr->flags)); 369 printf(" flags: 0x%" PRIx64 "\n", le64toh(hdr->flags));
370} 370}
371 371
372static int 372static int
373generate_header_arm64(struct arm64_image_header *hdr, int kernel_fd) 373generate_header_arm64(struct arm64_image_header *hdr, int kernel_fd)
374{ 374{
375 struct stat st; 375 struct stat st;
376 uint32_t flags; 376 uint32_t flags;
377 int error; 377 int error;
378 378
379 error = fstat(kernel_fd, &st); 379 error = fstat(kernel_fd, &st);
380 if (error == -1) { 380 if (error == -1) {
381 perror("stat"); 381 perror("stat");
382 return errno; 382 return errno;
383 } 383 }
384 384
385 flags = 0; 385 flags = 0;
386 flags |= ARM64_FLAGS_PAGE_SIZE_4K; 386 flags |= ARM64_FLAGS_PAGE_SIZE_4K;
387#if 0 387#if 0
388 flags |= ARM64_FLAGS_PHYS_PLACEMENT_ANY; 388 flags |= ARM64_FLAGS_PHYS_PLACEMENT_ANY;
389#endif 389#endif
390 390
391 const uint64_t dsize = update_image ? 391 const uint64_t dsize = update_image ?
392 st.st_size - sizeof(*hdr) : st.st_size; 392 (uint64_t)st.st_size - sizeof(*hdr) : (uint64_t)st.st_size;
393 393
394 memset(hdr, 0, sizeof(*hdr)); 394 memset(hdr, 0, sizeof(*hdr));
395 hdr->code0 = htole32(ARM64_CODE0); 395 hdr->code0 = htole32(ARM64_CODE0);
396 hdr->text_offset = htole64(image_entrypoint); 396 hdr->text_offset = htole64(image_entrypoint);
397 hdr->image_size = htole64(dsize); 397 hdr->image_size = htole64(dsize);
398 hdr->flags = htole32(flags); 398 hdr->flags = htole32(flags);
399 hdr->magic = htole32(ARM64_MAGIC); 399 hdr->magic = htole32(ARM64_MAGIC);
400 400
401 dump_header_arm64(hdr); 401 dump_header_arm64(hdr);
402 402
403 return 0; 403 return 0;
404} 404}
405 405
406static int 406static int
407write_image(void *hdr, size_t hdrlen, int kernel_fd, int image_fd) 407write_image(void *hdr, size_t hdrlen, int kernel_fd, int image_fd)
408{ 408{
409 uint8_t buf[4096]; 409 uint8_t buf[4096];
410 ssize_t rlen, wlen; 410 ssize_t rlen, wlen;
411 struct stat st; 411 struct stat st;
412 uint32_t size_buf[2]; 412 uint32_t size_buf[2];
413 int error; 413 int error;
414 414
415 error = fstat(kernel_fd, &st); 415 error = fstat(kernel_fd, &st);
416 if (error == -1) { 416 if (error == -1) {
417 perror("stat"); 417 perror("stat");
418 return errno; 418 return errno;
419 } 419 }
420 420
421 wlen = write(image_fd, hdr, hdrlen); 421 wlen = write(image_fd, hdr, hdrlen);
422 if (wlen != (ssize_t)hdrlen) { 422 if (wlen != (ssize_t)hdrlen) {
423 perror("short write"); 423 perror("short write");
424 return errno; 424 return errno;
425 } 425 }
426 426
427 if (image_type == IH_TYPE_SCRIPT) { 427 if (image_type == IH_TYPE_SCRIPT) {
428 size_buf[0] = htonl(st.st_size); 428 size_buf[0] = htonl(st.st_size);
429 size_buf[1] = htonl(0); 429 size_buf[1] = htonl(0);
430 wlen = write(image_fd, &size_buf, sizeof(size_buf)); 430 wlen = write(image_fd, &size_buf, sizeof(size_buf));
431 if (wlen != sizeof(size_buf)) { 431 if (wlen != sizeof(size_buf)) {
432 perror("short write"); 432 perror("short write");
433 return errno; 433 return errno;
434 } 434 }
435 } 435 }
436 436
437 if (update_image) { 437 if (update_image) {
438 if (lseek(kernel_fd, hdrlen, SEEK_SET) != (off_t)hdrlen) { 438 if (lseek(kernel_fd, hdrlen, SEEK_SET) != (off_t)hdrlen) {
439 perror("seek failed"); 439 perror("seek failed");
440 return errno; 440 return errno;
441 } 441 }
442 } 442 }
443 443
444 while ((rlen = read(kernel_fd, buf, sizeof(buf))) > 0) { 444 while ((rlen = read(kernel_fd, buf, sizeof(buf))) > 0) {
445 wlen = write(image_fd, buf, rlen); 445 wlen = write(image_fd, buf, rlen);
446 if (wlen != rlen) { 446 if (wlen != rlen) {
447 perror("short write"); 447 perror("short write");
448 return errno; 448 return errno;
449 } 449 }
450 } 450 }
451 451
452 return 0; 452 return 0;
453} 453}
454 454
455int 455int
456main(int argc, char *argv[]) 456main(int argc, char *argv[])
457{ 457{
458 struct uboot_image_header hdr_uimg; 458 struct uboot_image_header hdr_uimg;
459 struct arm64_image_header hdr_arm64; 459 struct arm64_image_header hdr_arm64;
460 const char *src, *dest; 460 const char *src, *dest;
461 char *ep; 461 char *ep;
462 int kernel_fd, image_fd; 462 int kernel_fd, image_fd;
463 int ch; 463 int ch;
464 unsigned long long num; 464 unsigned long long num;
465 465
466 while ((ch = getopt(argc, argv, "A:C:E:O:T:a:e:f:hm:n:u")) != -1) { 466 while ((ch = getopt(argc, argv, "A:C:E:O:T:a:e:f:hm:n:u")) != -1) {
467 switch (ch) { 467 switch (ch) {
468 case 'A': /* arch */ 468 case 'A': /* arch */
469 image_arch = get_arch(optarg); 469 image_arch = get_arch(optarg);
470 break; 470 break;
471 case 'C': /* comp */ 471 case 'C': /* comp */
472 image_comp = get_comp(optarg); 472 image_comp = get_comp(optarg);
473 break; 473 break;
474 case 'O': /* os */ 474 case 'O': /* os */
475 image_os = get_os(optarg); 475 image_os = get_os(optarg);
476 break; 476 break;
477 case 'T': /* type */ 477 case 'T': /* type */
478 image_type = get_type(optarg); 478 image_type = get_type(optarg);
479 break; 479 break;
480 case 'a': /* addr */ 480 case 'a': /* addr */
481 errno = 0; 481 errno = 0;
482 num = strtoull(optarg, &ep, 0); 482 num = strtoull(optarg, &ep, 0);
483 if (*ep != '\0' || (errno == ERANGE && 483 if (*ep != '\0' || (errno == ERANGE &&
484 (num == ULLONG_MAX || num == 0)) || 484 (num == ULLONG_MAX || num == 0)) ||
485 ((signed long long)num != (int32_t)num && 485 ((signed long long)num != (int32_t)num &&
486 num != (uint32_t)num)) 486 num != (uint32_t)num))
487 errx(1, "illegal number -- %s", optarg); 487 errx(1, "illegal number -- %s", optarg);
488 image_loadaddr = (uint32_t)num; 488 image_loadaddr = (uint32_t)num;
489 break; 489 break;
490 case 'E': /* ep (byte swapped) */ 490 case 'E': /* ep (byte swapped) */
491 case 'e': /* ep */ 491 case 'e': /* ep */
492 errno = 0; 492 errno = 0;
493 num = strtoull(optarg, &ep, 0); 493 num = strtoull(optarg, &ep, 0);
494 if (*ep != '\0' || (errno == ERANGE && 494 if (*ep != '\0' || (errno == ERANGE &&
495 (num == ULLONG_MAX || num == 0)) || 495 (num == ULLONG_MAX || num == 0)) ||
496 ((signed long long)num != (int32_t)num && 496 ((signed long long)num != (int32_t)num &&
497 num != (uint32_t)num)) 497 num != (uint32_t)num))
498 errx(1, "illegal number -- %s", optarg); 498 errx(1, "illegal number -- %s", optarg);
499 image_entrypoint = (uint32_t)num; 499 image_entrypoint = (uint32_t)num;
500 if (ch == 'E') 500 if (ch == 'E')
501 image_entrypoint = bswap32(image_entrypoint); 501 image_entrypoint = bswap32(image_entrypoint);
502 break; 502 break;
503 case 'f': /* image format */ 503 case 'f': /* image format */
504 image_format = get_image_format(optarg); 504 image_format = get_image_format(optarg);
505 break; 505 break;
506 case 'm': /* magic */ 506 case 'm': /* magic */
507 errno = 0; 507 errno = 0;
508 num = strtoul(optarg, &ep, 0); 508 num = strtoul(optarg, &ep, 0);
509 if (*ep != '\0' || (errno == ERANGE && 509 if (*ep != '\0' || (errno == ERANGE &&
510 (num == ULONG_MAX || num == 0))) 510 (num == ULONG_MAX || num == 0)))
511 errx(1, "illegal number -- %s", optarg); 511 errx(1, "illegal number -- %s", optarg);
512 image_magic = (uint32_t)num; 512 image_magic = (uint32_t)num;
513 break; 513 break;
514 case 'n': /* name */ 514 case 'n': /* name */
515 image_name = strdup(optarg); 515 image_name = strdup(optarg);
516 break; 516 break;
517 case 'u': /* update image */ 517 case 'u': /* update image */
518 update_image = 1; 518 update_image = 1;
519 break; 519 break;
520 case 'h': 520 case 'h':
521 default: 521 default:
522 usage(); 522 usage();
523 /* NOTREACHED */ 523 /* NOTREACHED */
524 } 524 }
525 } 525 }
526 argc -= optind; 526 argc -= optind;
527 argv += optind; 527 argv += optind;
528 528
529 if (argc != 2) 529 if (argc != 2)
530 usage(); 530 usage();
531 531
532 if (image_entrypoint == 0) 532 if (image_entrypoint == 0)
533 image_entrypoint = image_loadaddr; 533 image_entrypoint = image_loadaddr;
534 534
535 switch (image_format) { 535 switch (image_format) {
536 case FMT_UIMG: 536 case FMT_UIMG:
537 if (image_arch == IH_ARCH_UNKNOWN || 537 if (image_arch == IH_ARCH_UNKNOWN ||
538 image_type == IH_TYPE_UNKNOWN || 538 image_type == IH_TYPE_UNKNOWN ||
539 image_name == NULL) 539 image_name == NULL)
540 usage(); 540 usage();
541 /* NOTREACHED */ 541 /* NOTREACHED */
542 542
543 switch (image_type) { 543 switch (image_type) {
544 case IH_TYPE_SCRIPT: 544 case IH_TYPE_SCRIPT:
545 case IH_TYPE_RAMDISK: 545 case IH_TYPE_RAMDISK:
546 case IH_TYPE_KERNEL_NOLOAD: 546 case IH_TYPE_KERNEL_NOLOAD:
547 break; 547 break;
548 default: 548 default:
549 if (image_loadaddr == 0) 549 if (image_loadaddr == 0)
550 usage(); 550 usage();
551 /* NOTREACHED */ 551 /* NOTREACHED */
552 break; 552 break;
553 } 553 }
554 break; 554 break;
555 555
556 case FMT_ARM64: 556 case FMT_ARM64:
557 if (image_arch != IH_ARCH_UNKNOWN && 557 if (image_arch != IH_ARCH_UNKNOWN &&
558 image_arch != IH_ARCH_ARM64) 558 image_arch != IH_ARCH_ARM64)
559 usage(); 559 usage();
560 /* NOTREACHED */ 560 /* NOTREACHED */
561 561
562 break; 562 break;
563 563
564 default: 564 default:
565 usage(); 565 usage();
566 /* NOTREACHED */ 566 /* NOTREACHED */
567 } 567 }
568 568
569 src = argv[0]; 569 src = argv[0];
570 dest = argv[1]; 570 dest = argv[1];
571 571
572 kernel_fd = open(src, O_RDONLY); 572 kernel_fd = open(src, O_RDONLY);
573 if (kernel_fd == -1) { 573 if (kernel_fd == -1) {
574 perror("open kernel"); 574 perror("open kernel");
575 return EXIT_FAILURE; 575 return EXIT_FAILURE;
576 } 576 }
577 image_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0666); 577 image_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0666);
578 if (image_fd == -1) { 578 if (image_fd == -1) {
579 perror("open image"); 579 perror("open image");
580 return EXIT_FAILURE; 580 return EXIT_FAILURE;
581 } 581 }
582 582
583 printf(" image type: %s\n", get_image_format_name(image_format)); 583 printf(" image type: %s\n", get_image_format_name(image_format));
584 584
585 switch (image_format) { 585 switch (image_format) {
586 case FMT_UIMG: 586 case FMT_UIMG:
587 if (generate_header_uimg(&hdr_uimg, kernel_fd) != 0) 587 if (generate_header_uimg(&hdr_uimg, kernel_fd) != 0)
588 return EXIT_FAILURE; 588 return EXIT_FAILURE;
589 589
590 if (write_image(&hdr_uimg, sizeof(hdr_uimg), 590 if (write_image(&hdr_uimg, sizeof(hdr_uimg),
591 kernel_fd, image_fd) != 0) 591 kernel_fd, image_fd) != 0)
592 return EXIT_FAILURE; 592 return EXIT_FAILURE;
593 593
594 break; 594 break;
595 case FMT_ARM64: 595 case FMT_ARM64:
596 if (generate_header_arm64(&hdr_arm64, kernel_fd) != 0) 596 if (generate_header_arm64(&hdr_arm64, kernel_fd) != 0)
597 return EXIT_FAILURE; 597 return EXIT_FAILURE;
598 598
599 if (write_image(&hdr_arm64, sizeof(hdr_arm64), 599 if (write_image(&hdr_arm64, sizeof(hdr_arm64),
600 kernel_fd, image_fd) != 0) 600 kernel_fd, image_fd) != 0)
601 return EXIT_FAILURE; 601 return EXIT_FAILURE;
602 602
603 break; 603 break;
604 default: 604 default:
605 break; 605 break;
606 } 606 }
607 607
608 close(image_fd); 608 close(image_fd);
609 close(kernel_fd); 609 close(kernel_fd);
610 610
611 return EXIT_SUCCESS; 611 return EXIT_SUCCESS;
612} 612}