| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: mkubootimage.c,v 1.6 2011/02/26 20:03:09 phx Exp $ */ | | 1 | /* $NetBSD: mkubootimage.c,v 1.7 2011/06/08 05:54:38 matt 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 | * |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
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.6 2011/02/26 20:03:09 phx Exp $"); | | 33 | __RCSID("$NetBSD: mkubootimage.c,v 1.7 2011/06/08 05:54:38 matt 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 <err.h> | | 37 | #include <err.h> |
38 | #include <errno.h> | | 38 | #include <errno.h> |
39 | #include <fcntl.h> | | 39 | #include <fcntl.h> |
40 | #include <limits.h> | | 40 | #include <limits.h> |
41 | #include <stdint.h> | | 41 | #include <stdint.h> |
42 | #include <stdio.h> | | 42 | #include <stdio.h> |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <string.h> | | 44 | #include <string.h> |
45 | #include <time.h> | | 45 | #include <time.h> |
46 | #include <unistd.h> | | 46 | #include <unistd.h> |
| @@ -74,122 +74,178 @@ struct uboot_os { | | | @@ -74,122 +74,178 @@ struct uboot_os { |
74 | static enum uboot_image_os | | 74 | static enum uboot_image_os |
75 | get_os(const char *name) | | 75 | get_os(const char *name) |
76 | { | | 76 | { |
77 | unsigned int i; | | 77 | unsigned int i; |
78 | | | 78 | |
79 | for (i = 0; i < __arraycount(uboot_os); i++) { | | 79 | for (i = 0; i < __arraycount(uboot_os); i++) { |
80 | if (strcmp(uboot_os[i].name, name) == 0) | | 80 | if (strcmp(uboot_os[i].name, name) == 0) |
81 | return uboot_os[i].os; | | 81 | return uboot_os[i].os; |
82 | } | | 82 | } |
83 | | | 83 | |
84 | return IH_OS_UNKNOWN; | | 84 | return IH_OS_UNKNOWN; |
85 | } | | 85 | } |
86 | | | 86 | |
| | | 87 | static const char * |
| | | 88 | get_os_name(enum uboot_image_os os) |
| | | 89 | { |
| | | 90 | unsigned int i; |
| | | 91 | |
| | | 92 | for (i = 0; i < __arraycount(uboot_os); i++) { |
| | | 93 | if (uboot_os[i].os == os) |
| | | 94 | return uboot_os[i].name; |
| | | 95 | } |
| | | 96 | |
| | | 97 | return "Unknown"; |
| | | 98 | } |
| | | 99 | |
87 | struct uboot_arch { | | 100 | struct uboot_arch { |
88 | enum uboot_image_arch arch; | | 101 | enum uboot_image_arch arch; |
89 | const char *name; | | 102 | const char *name; |
90 | } uboot_arch[] = { | | 103 | } uboot_arch[] = { |
91 | { IH_ARCH_ARM, "arm" }, | | 104 | { IH_ARCH_ARM, "arm" }, |
92 | { IH_ARCH_MIPS, "mips" }, | | 105 | { IH_ARCH_MIPS, "mips" }, |
93 | { IH_ARCH_MIPS64, "mips64" }, | | 106 | { IH_ARCH_MIPS64, "mips64" }, |
94 | { IH_ARCH_PPC, "powerpc" }, | | 107 | { IH_ARCH_PPC, "powerpc" }, |
95 | }; | | 108 | }; |
96 | | | 109 | |
97 | static enum uboot_image_arch | | 110 | static enum uboot_image_arch |
98 | get_arch(const char *name) | | 111 | get_arch(const char *name) |
99 | { | | 112 | { |
100 | unsigned int i; | | 113 | unsigned int i; |
101 | | | 114 | |
102 | for (i = 0; i < __arraycount(uboot_arch); i++) { | | 115 | for (i = 0; i < __arraycount(uboot_arch); i++) { |
103 | if (strcmp(uboot_arch[i].name, name) == 0) | | 116 | if (strcmp(uboot_arch[i].name, name) == 0) |
104 | return uboot_arch[i].arch; | | 117 | return uboot_arch[i].arch; |
105 | } | | 118 | } |
106 | | | 119 | |
107 | return IH_ARCH_UNKNOWN; | | 120 | return IH_ARCH_UNKNOWN; |
108 | } | | 121 | } |
109 | | | 122 | |
| | | 123 | static const char * |
| | | 124 | get_arch_name(enum uboot_image_arch arch) |
| | | 125 | { |
| | | 126 | unsigned int i; |
| | | 127 | |
| | | 128 | for (i = 0; i < __arraycount(uboot_arch); i++) { |
| | | 129 | if (uboot_arch[i].arch == arch) |
| | | 130 | return uboot_arch[i].name; |
| | | 131 | } |
| | | 132 | |
| | | 133 | return "Unknown"; |
| | | 134 | } |
| | | 135 | |
110 | struct uboot_type { | | 136 | struct uboot_type { |
111 | enum uboot_image_type type; | | 137 | enum uboot_image_type type; |
112 | const char *name; | | 138 | const char *name; |
113 | } uboot_type[] = { | | 139 | } uboot_type[] = { |
114 | { IH_TYPE_STANDALONE, "standalone" }, | | 140 | { IH_TYPE_STANDALONE, "standalone" }, |
115 | { IH_TYPE_KERNEL, "kernel" }, | | 141 | { IH_TYPE_KERNEL, "kernel" }, |
116 | { IH_TYPE_RAMDISK, "ramdisk" }, | | 142 | { IH_TYPE_RAMDISK, "ramdisk" }, |
117 | { IH_TYPE_FILESYSTEM, "fs" }, | | 143 | { IH_TYPE_FILESYSTEM, "fs" }, |
118 | }; | | 144 | }; |
119 | | | 145 | |
120 | static enum uboot_image_type | | 146 | static enum uboot_image_type |
121 | get_type(const char *name) | | 147 | get_type(const char *name) |
122 | { | | 148 | { |
123 | unsigned int i; | | 149 | unsigned int i; |
124 | | | 150 | |
125 | for (i = 0; i < __arraycount(uboot_type); i++) { | | 151 | for (i = 0; i < __arraycount(uboot_type); i++) { |
126 | if (strcmp(uboot_type[i].name, name) == 0) | | 152 | if (strcmp(uboot_type[i].name, name) == 0) |
127 | return uboot_type[i].type; | | 153 | return uboot_type[i].type; |
128 | } | | 154 | } |
129 | | | 155 | |
130 | return IH_TYPE_UNKNOWN; | | 156 | return IH_TYPE_UNKNOWN; |
131 | } | | 157 | } |
132 | | | 158 | |
| | | 159 | static const char * |
| | | 160 | get_type_name(enum uboot_image_type type) |
| | | 161 | { |
| | | 162 | unsigned int i; |
| | | 163 | |
| | | 164 | for (i = 0; i < __arraycount(uboot_type); i++) { |
| | | 165 | if (uboot_type[i].type == type) |
| | | 166 | return uboot_type[i].name; |
| | | 167 | } |
| | | 168 | |
| | | 169 | return "Unknown"; |
| | | 170 | } |
| | | 171 | |
133 | struct uboot_comp { | | 172 | struct uboot_comp { |
134 | enum uboot_image_comp comp; | | 173 | enum uboot_image_comp comp; |
135 | const char *name; | | 174 | const char *name; |
136 | } uboot_comp[] = { | | 175 | } uboot_comp[] = { |
137 | { IH_COMP_NONE, "none" }, | | 176 | { IH_COMP_NONE, "none" }, |
138 | { IH_COMP_GZIP, "gz" }, | | 177 | { IH_COMP_GZIP, "gz" }, |
139 | { IH_COMP_BZIP2, "bz2" }, | | 178 | { IH_COMP_BZIP2, "bz2" }, |
140 | }; | | 179 | }; |
141 | | | 180 | |
142 | static enum uboot_image_comp | | 181 | static enum uboot_image_comp |
143 | get_comp(const char *name) | | 182 | get_comp(const char *name) |
144 | { | | 183 | { |
145 | unsigned int i; | | 184 | unsigned int i; |
146 | | | 185 | |
147 | for (i = 0; i < __arraycount(uboot_comp); i++) { | | 186 | for (i = 0; i < __arraycount(uboot_comp); i++) { |
148 | if (strcmp(uboot_comp[i].name, name) == 0) | | 187 | if (strcmp(uboot_comp[i].name, name) == 0) |
149 | return uboot_comp[i].comp; | | 188 | return uboot_comp[i].comp; |
150 | } | | 189 | } |
151 | | | 190 | |
152 | return IH_TYPE_UNKNOWN; | | 191 | return IH_TYPE_UNKNOWN; |
153 | } | | 192 | } |
154 | | | 193 | |
| | | 194 | static const char * |
| | | 195 | get_comp_name(enum uboot_image_comp comp) |
| | | 196 | { |
| | | 197 | unsigned int i; |
| | | 198 | |
| | | 199 | for (i = 0; i < __arraycount(uboot_comp); i++) { |
| | | 200 | if (uboot_comp[i].comp == comp) |
| | | 201 | return uboot_comp[i].name; |
| | | 202 | } |
| | | 203 | |
| | | 204 | return "Unknown"; |
| | | 205 | } |
| | | 206 | |
155 | static void | | 207 | static void |
156 | usage(void) | | 208 | usage(void) |
157 | { | | 209 | { |
158 | fprintf(stderr, "usage: mkubootimage -A <arm|mips|mips64|powerpc>"); | | 210 | fprintf(stderr, "usage: mkubootimage -A <arm|mips|mips64|powerpc>"); |
159 | fprintf(stderr, " -C <none|gz|bz2>"); | | 211 | fprintf(stderr, " -C <none|gz|bz2>"); |
160 | fprintf(stderr, " -O <openbsd|netbsd|freebsd|linux>"); | | 212 | fprintf(stderr, " -O <openbsd|netbsd|freebsd|linux>"); |
161 | fprintf(stderr, " -T <standalone|kernel|ramdisk|fs>"); | | 213 | fprintf(stderr, " -T <standalone|kernel|ramdisk|fs>"); |
162 | fprintf(stderr, " -a <addr> [-e <ep>] -n <name>"); | | 214 | fprintf(stderr, " -a <addr> [-e <ep>] -n <name>"); |
163 | fprintf(stderr, " <srcfile> <dstfile>\n"); | | 215 | fprintf(stderr, " <srcfile> <dstfile>\n"); |
164 | | | 216 | |
165 | exit(EXIT_FAILURE); | | 217 | exit(EXIT_FAILURE); |
166 | } | | 218 | } |
167 | | | 219 | |
168 | static void | | 220 | static void |
169 | dump_header(struct uboot_image_header *hdr) | | 221 | dump_header(struct uboot_image_header *hdr) |
170 | { | | 222 | { |
171 | time_t tm = ntohl(hdr->ih_time); | | 223 | time_t tm = ntohl(hdr->ih_time); |
172 | | | 224 | |
173 | printf(" magic: 0x%08x\n", ntohl(hdr->ih_magic)); | | 225 | printf(" magic: 0x%08x\n", ntohl(hdr->ih_magic)); |
174 | printf(" time: %s", ctime(&tm)); | | 226 | printf(" time: %s", ctime(&tm)); |
175 | printf(" size: %u\n", ntohl(hdr->ih_size)); | | 227 | printf(" size: %u\n", ntohl(hdr->ih_size)); |
176 | printf(" load addr: 0x%08x\n", ntohl(hdr->ih_load)); | | 228 | printf(" load addr: 0x%08x\n", ntohl(hdr->ih_load)); |
177 | printf(" entry point: 0x%08x\n", ntohl(hdr->ih_ep)); | | 229 | printf(" entry point: 0x%08x\n", ntohl(hdr->ih_ep)); |
178 | printf(" data crc: 0x%08x\n", ntohl(hdr->ih_dcrc)); | | 230 | printf(" data crc: 0x%08x\n", ntohl(hdr->ih_dcrc)); |
179 | printf(" os: %d\n", hdr->ih_os); | | 231 | printf(" os: %d (%s)\n", hdr->ih_os, |
180 | printf(" arch: %d\n", hdr->ih_arch); | | 232 | get_os_name(hdr->ih_os)); |
181 | printf(" type: %d\n", hdr->ih_type); | | 233 | printf(" arch: %d (%s)\n", hdr->ih_arch, |
182 | printf(" comp: %d\n", hdr->ih_comp); | | 234 | get_arch_name(hdr->ih_arch)); |
| | | 235 | printf(" type: %d (%s)\n", hdr->ih_type, |
| | | 236 | get_type_name(hdr->ih_type)); |
| | | 237 | printf(" comp: %d (%s)\n", hdr->ih_comp, |
| | | 238 | get_comp_name(hdr->ih_comp)); |
183 | printf(" name: %s\n", hdr->ih_name); | | 239 | printf(" name: %s\n", hdr->ih_name); |
184 | printf(" header crc: 0x%08x\n", hdr->ih_hcrc); | | 240 | printf(" header crc: 0x%08x\n", hdr->ih_hcrc); |
185 | } | | 241 | } |
186 | | | 242 | |
187 | static int | | 243 | static int |
188 | generate_header(struct uboot_image_header *hdr, int kernel_fd) | | 244 | generate_header(struct uboot_image_header *hdr, int kernel_fd) |
189 | { | | 245 | { |
190 | uint8_t *p; | | 246 | uint8_t *p; |
191 | struct stat st; | | 247 | struct stat st; |
192 | uint32_t crc; | | 248 | uint32_t crc; |
193 | int error; | | 249 | int error; |
194 | | | 250 | |
195 | error = fstat(kernel_fd, &st); | | 251 | error = fstat(kernel_fd, &st); |
| @@ -212,27 +268,27 @@ generate_header(struct uboot_image_heade | | | @@ -212,27 +268,27 @@ generate_header(struct uboot_image_heade |
212 | munmap(p, st.st_size); | | 268 | munmap(p, st.st_size); |
213 | | | 269 | |
214 | memset(hdr, 0, sizeof(*hdr)); | | 270 | memset(hdr, 0, sizeof(*hdr)); |
215 | hdr->ih_magic = htonl(IH_MAGIC); | | 271 | hdr->ih_magic = htonl(IH_MAGIC); |
216 | hdr->ih_time = htonl(st.st_mtime); | | 272 | hdr->ih_time = htonl(st.st_mtime); |
217 | hdr->ih_size = htonl(st.st_size); | | 273 | hdr->ih_size = htonl(st.st_size); |
218 | hdr->ih_load = htonl(image_loadaddr); | | 274 | hdr->ih_load = htonl(image_loadaddr); |
219 | hdr->ih_ep = htonl(image_entrypoint); | | 275 | hdr->ih_ep = htonl(image_entrypoint); |
220 | hdr->ih_dcrc = htonl(crc); | | 276 | hdr->ih_dcrc = htonl(crc); |
221 | hdr->ih_os = image_os; | | 277 | hdr->ih_os = image_os; |
222 | hdr->ih_arch = image_arch; | | 278 | hdr->ih_arch = image_arch; |
223 | hdr->ih_type = image_type; | | 279 | hdr->ih_type = image_type; |
224 | hdr->ih_comp = image_comp; | | 280 | hdr->ih_comp = image_comp; |
225 | strncpy((char *)hdr->ih_name, image_name, sizeof(hdr->ih_name)); | | 281 | strlcpy((char *)hdr->ih_name, image_name, sizeof(hdr->ih_name)); |
226 | crc = crc32((void *)hdr, sizeof(*hdr)); | | 282 | crc = crc32((void *)hdr, sizeof(*hdr)); |
227 | hdr->ih_hcrc = htonl(crc); | | 283 | hdr->ih_hcrc = htonl(crc); |
228 | | | 284 | |
229 | dump_header(hdr); | | 285 | dump_header(hdr); |
230 | | | 286 | |
231 | return 0; | | 287 | return 0; |
232 | } | | 288 | } |
233 | | | 289 | |
234 | static int | | 290 | static int |
235 | write_image(struct uboot_image_header *hdr, int kernel_fd, int image_fd) | | 291 | write_image(struct uboot_image_header *hdr, int kernel_fd, int image_fd) |
236 | { | | 292 | { |
237 | uint8_t buf[4096]; | | 293 | uint8_t buf[4096]; |
238 | ssize_t rlen, wlen; | | 294 | ssize_t rlen, wlen; |