241bb334006f6c1a5f421233db4f2f287e68f2e5
2 * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com>
4 * The format of the header this tool generates was first documented by
5 * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the
6 * same purpose. I have created this reimplementation at his request. The
7 * original script can be found at:
8 * <https://github.com/riptidewave93/meraki-partbuilder>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
23 #include <arpa/inet.h>
27 #define PADDING_BYTE 0xff
29 #define HDR_LENGTH 0x00000400
30 #define HDR_OFF_MAGIC1 0
31 #define HDR_OFF_HDRLEN 4
32 #define HDR_OFF_IMAGELEN 8
33 #define HDR_OFF_CHECKSUM 12
34 #define HDR_OFF_MAGIC2 32
35 #define HDR_OFF_FILLER 36
36 #define HDR_OFF_STATICHASH 40
41 unsigned char statichash
[20];
49 static char *progname
;
51 static char *board_id
;
52 static const struct board_info
*board
;
54 static const struct board_info boards
[] = {
57 .description
= "Meraki MR18 Access Point",
59 .imagelen
= 0x00800000,
60 .statichash
= {0xda, 0x39, 0xa3, 0xee, 0x5e,
61 0x6b, 0x4b, 0x0d, 0x32, 0x55,
62 0xbf, 0xef, 0x95, 0x60, 0x18,
63 0x90, 0xaf, 0xd8, 0x07, 0x09},
65 /* terminating entry */
72 #define ERR(fmt, ...) do { \
74 fprintf(stderr, "[%s] *** error: " fmt "\n", \
75 progname, ## __VA_ARGS__); \
78 #define ERRS(fmt, ...) do { \
81 fprintf(stderr, "[%s] *** error: " fmt "\n", \
82 progname, ## __VA_ARGS__, strerror(save)); \
85 static const struct board_info
*find_board(const char *id
)
87 const struct board_info
*ret
;
88 const struct board_info
*board
;
91 for (board
= boards
; board
->id
!= NULL
; board
++) {
92 if (strcasecmp(id
, board
->id
) == 0) {
101 static void usage(int status
)
103 FILE *stream
= (status
!= EXIT_SUCCESS
) ? stderr
: stdout
;
104 const struct board_info
*board
;
106 fprintf(stream
, "Usage: %s [OPTIONS...]\n", progname
);
110 " -B <board> create image for the board specified with <board>\n"
111 " -i <file> read kernel image from the file <file>\n"
112 " -o <file> write output to the file <file>\n"
113 " -s strip padding from the end of the image\n"
114 " -h show this screen\n"
117 fprintf(stream
, "\nBoards:\n");
118 for (board
= boards
; board
->id
!= NULL
; board
++)
119 fprintf(stream
, " %-16s%s\n", board
->id
, board
->description
);
124 void writel(unsigned char *buf
, size_t offset
, uint32_t value
)
126 value
= htonl(value
);
127 memcpy(buf
+ offset
, &value
, sizeof(uint32_t));
130 int main(int argc
, char *argv
[])
132 int ret
= EXIT_FAILURE
;
135 unsigned char *kernel
;
138 bool strip_padding
= false;
139 char *ofname
= NULL
, *ifname
= NULL
;
142 progname
= basename(argv
[0]);
147 c
= getopt(argc
, argv
, "B:i:o:sh");
162 strip_padding
= true;
173 if (board_id
== NULL
) {
174 ERR("no board specified");
178 board
= find_board(board_id
);
180 ERR("unknown board \"%s\"", board_id
);
184 if (ifname
== NULL
) {
185 ERR("no input file specified");
189 if (ofname
== NULL
) {
190 ERR("no output file specified");
194 in
= fopen(ifname
, "r");
196 ERRS("could not open \"%s\" for reading: %s", ifname
);
200 buflen
= board
->imagelen
;
201 kspace
= buflen
- HDR_LENGTH
;
203 /* Get kernel length */
204 fseek(in
, 0, SEEK_END
);
209 ERR("file \"%s\" is too big - max size: 0x%08lX\n",
214 /* If requested, resize buffer to remove padding */
216 buflen
= klen
+ HDR_LENGTH
;
218 /* Allocate and initialize buffer for final image */
219 buf
= malloc(buflen
);
221 ERRS("no memory for buffer: %s\n");
224 memset(buf
, PADDING_BYTE
, buflen
);
227 kernel
= buf
+ HDR_LENGTH
;
228 fread(kernel
, klen
, 1, in
);
230 /* Write magic values and filler */
231 writel(buf
, HDR_OFF_MAGIC1
, board
->magic
);
232 writel(buf
, HDR_OFF_MAGIC2
, board
->magic
);
233 writel(buf
, HDR_OFF_FILLER
, 0);
235 /* Write header and image length */
236 writel(buf
, HDR_OFF_HDRLEN
, HDR_LENGTH
);
237 writel(buf
, HDR_OFF_IMAGELEN
, klen
);
239 /* Write checksum and static hash */
240 sha1_csum(kernel
, klen
, buf
+ HDR_OFF_CHECKSUM
);
241 memcpy(buf
+ HDR_OFF_STATICHASH
, board
->statichash
, 20);
243 /* Save finished image */
244 out
= fopen(ofname
, "w");
246 ERRS("could not open \"%s\" for writing: %s", ofname
);
249 fwrite(buf
, buflen
, 1, out
);