1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2021 Sungbo Eo <mans0n@gorani.run>
5 * This code is based on mkdhpimg.c and mkzcfw.c
6 * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
7 * Copyright (c) 2016 FUKAUMI Naoki <naobsd@gmail.com>
9 * Checksum algorithm is derived from add_iptime_fw_header.c
10 * Copyright (C) 2020 Jaehoon You <teslamint@gmail.com>
27 #if !defined(__BYTE_ORDER)
28 #error "Unknown byte order"
31 #if (__BYTE_ORDER == __BIG_ENDIAN)
32 #define HOST_TO_LE32(x) bswap_32(x)
33 #elif (__BYTE_ORDER == __LITTLE_ENDIAN)
34 #define HOST_TO_LE32(x) (x)
36 #error "Unsupported endianness"
39 #define FW_VERSION "00_000"
47 } __attribute__ ((packed
));
51 size_t payload_offset
;
54 struct board_info boards
[] = {
55 { .model
= "ax2004m", .payload_offset
= 0x38 },
56 { .model
= "ax8004m", .payload_offset
= 0x38 },
60 struct board_info
*find_board(const char *model
)
62 struct board_info
*ret
= NULL
;
63 struct board_info
*board
;
65 for (board
= boards
; board
->model
!= NULL
; board
++) {
66 if (strcmp(model
, board
->model
) == 0) {
75 uint32_t make_checksum(struct fw_header
*header
, uint8_t *payload
, int size
)
79 /* get CRC of header */
80 checksum
= cyg_crc32_accumulate(~0L, header
, sizeof(*header
));
82 /* get CRC of payload buffer with header CRC as initial value */
83 return (uint32_t)cyg_crc32_accumulate(checksum
, payload
, size
);
86 void make_header(struct board_info
*board
, uint8_t *buffer
, size_t img_size
)
88 struct fw_header
*header
= (struct fw_header
*)buffer
;
91 strncpy((char *)header
->model
, board
->model
, sizeof(header
->model
)-1);
92 strncpy((char *)header
->version
, FW_VERSION
, sizeof(header
->version
)-1);
93 header
->size
= HOST_TO_LE32(img_size
);
94 checksum
= make_checksum(header
, buffer
+ board
->payload_offset
, img_size
);
95 header
->checksum
= HOST_TO_LE32(checksum
);
98 int main(int argc
, const char *argv
[])
100 const char *model_name
, *img_in
, *img_out
;
101 struct board_info
*board
;
102 int file_in
, file_out
;
104 size_t size_in
, size_out
;
108 fprintf(stderr
, "Usage: %s <model> <input> <output>\n", argv
[0]);
111 model_name
= argv
[1];
115 board
= find_board(model_name
);
117 fprintf(stderr
, "%s: Not supported model\n", model_name
);
121 if ((file_in
= open(img_in
, O_RDONLY
)) == -1)
122 err(EXIT_FAILURE
, "%s", img_in
);
124 if (fstat(file_in
, &stat_in
) == -1)
125 err(EXIT_FAILURE
, "%s", img_in
);
127 size_in
= stat_in
.st_size
;
128 size_out
= board
->payload_offset
+ size_in
;
130 if ((buffer
= malloc(size_out
)) == NULL
)
131 err(EXIT_FAILURE
, "malloc");
133 read(file_in
, buffer
+ board
->payload_offset
, size_in
);
136 memset(buffer
, 0, board
->payload_offset
);
138 make_header(board
, buffer
, size_in
);
140 if ((file_out
= creat(img_out
, 0644)) == -1)
141 err(EXIT_FAILURE
, "%s", img_out
);
142 write(file_out
, buffer
, size_out
);