9cddda3575314cad8389d169a29dce92849f9534
2 * mkbrnimg.c - partially based on OpenWrt's wndr3700.c
4 * Copyright (C) 2011 Tobias Diedrich <ranma+openwrt@tdiedrich.de>
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <netinet/in.h>
31 #define BPB 8 /* bits/byte */
33 static uint32_t crc32
[1<<BPB
];
35 static char *output_file
= "default-brnImage";
36 static uint32_t magic
= 0x12345678;
37 static char *signature
= "BRNDTW502";
38 static uint32_t crc32_poly
= 0x2083b8ed;
40 static void init_crc32()
42 const uint32_t poly
= ntohl(crc32_poly
);
45 for (n
= 0; n
< 1<<BPB
; n
++) {
49 for (bit
= 0; bit
< BPB
; bit
++)
50 crc
= (crc
& 1) ? (poly
^ (crc
>> 1)) : (crc
>> 1);
55 static uint32_t crc32buf(const void *buf
, size_t len
)
57 uint32_t crc
= 0xFFFFFFFF;
58 const uint8_t *in
= buf
;
60 for (; len
; len
--, in
++)
61 crc
= crc32
[(uint8_t)crc
^ *in
] ^ (crc
>> BPB
);
65 static void usage(const char *) __attribute__ (( __noreturn__
));
67 static void usage(const char *mess
)
69 fprintf(stderr
, "Error: %s\n", mess
);
70 fprintf(stderr
, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] [-p crc32 poly] kernel_file [additional files]\n");
71 fprintf(stderr
, "\n");
75 static void parseopts(int *argc
, char ***argv
)
80 while ((res
= getopt(*argc
, *argv
, "o:m:s:p:")) != -1) {
83 usage("Unknown option");
89 magic
= strtoul(optarg
, &endptr
, 0);
90 if (endptr
== optarg
|| *endptr
!= 0)
91 usage("magic must be a decimal or hexadecimal 32-bit value");
97 crc32_poly
= strtoul(optarg
, &endptr
, 0);
98 if (endptr
== optarg
|| *endptr
!= 0)
99 usage("'crc32 poly' must be a decimal or hexadecimal 32-bit value");
107 static void appendfile(int outfd
, char *path
, int kernel
) {
109 size_t len
, padded_len
;
115 memset(padding
, 0xff, sizeof(padding
));
118 if ((fd
= open(path
, O_RDONLY
)) < 0
119 || (len
= lseek(fd
, 0, SEEK_END
)) < 0
120 || (input_file
= mmap(0, len
, PROT_READ
, MAP_SHARED
, fd
, 0)) == (void *) (-1)
123 fprintf(stderr
, "Error mapping file '%s': %s\n", path
, strerror(errno
));
127 // kernel should be lzma compressed image, not uImage
129 (input_file
[0] != (char)0x5d ||
130 input_file
[1] != (char)0x00 ||
131 input_file
[2] != (char)0x00 ||
132 input_file
[3] != (char)0x80)) {
133 fprintf(stderr
, "lzma signature not found on kernel image.\n");
138 crc
= crc32buf(input_file
, len
);
139 fprintf(stderr
, "crc32 for '%s' is %08x.\n", path
, crc
);
142 write(outfd
, input_file
, len
);
145 padded_len
= ((len
+ sizeof(footer
) + sizeof(padding
) - 1) & ~(sizeof(padding
) - 1)) - sizeof(footer
);
146 fprintf(stderr
, "len=%08zx padded_len=%08zx\n", len
, padded_len
);
147 write(outfd
, padding
, padded_len
- len
);
150 footer
[0] = (len
>> 0) & 0xff;
151 footer
[1] = (len
>> 8) & 0xff;
152 footer
[2] = (len
>> 16) & 0xff;
153 footer
[3] = (len
>> 24) & 0xff;
154 footer
[4] = (magic
>> 0) & 0xff;
155 footer
[5] = (magic
>> 8) & 0xff;
156 footer
[6] = (magic
>> 16) & 0xff;
157 footer
[7] = (magic
>> 24) & 0xff;
158 footer
[8] = (crc
>> 0) & 0xff;
159 footer
[9] = (crc
>> 8) & 0xff;
160 footer
[10] = (crc
>> 16) & 0xff;
161 footer
[11] = (crc
>> 24) & 0xff;
162 write(outfd
, footer
, sizeof(footer
));
164 munmap(input_file
, len
);
167 int main(int argc
, char **argv
)
172 parseopts(&argc
, &argv
);
175 usage("wrong number of arguments");
177 if ((outfd
= open(output_file
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
179 fprintf(stderr
, "Error opening '%s' for writing: %s\n", output_file
, strerror(errno
));
183 for (i
=0; i
<argc
; i
++) {
184 appendfile(outfd
, argv
[i
], i
== 0);
186 write(outfd
, signature
, strlen(signature
)+1);