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
= "a6004mx", .payload_offset
= 0x800 },
56 { .model
= "ax2004m", .payload_offset
= 0x38 },
57 { .model
= "ax8004m", .payload_offset
= 0x38 },
61 struct board_info
*find_board(const char *model
)
63 struct board_info
*ret
= NULL
;
64 struct board_info
*board
;
66 for (board
= boards
; board
->model
!= NULL
; board
++) {
67 if (strcmp(model
, board
->model
) == 0) {
76 uint32_t make_checksum(struct fw_header
*header
, uint8_t *payload
, int size
)
80 /* get CRC of header */
81 checksum
= cyg_crc32_accumulate(~0L, header
, sizeof(*header
));
83 /* get CRC of payload buffer with header CRC as initial value */
84 return (uint32_t)cyg_crc32_accumulate(checksum
, payload
, size
);
87 void make_header(struct board_info
*board
, uint8_t *buffer
, size_t img_size
)
89 struct fw_header
*header
= (struct fw_header
*)buffer
;
92 strncpy((char *)header
->model
, board
->model
, sizeof(header
->model
)-1);
93 strncpy((char *)header
->version
, FW_VERSION
, sizeof(header
->version
)-1);
94 header
->size
= HOST_TO_LE32(img_size
);
95 checksum
= make_checksum(header
, buffer
+ board
->payload_offset
, img_size
);
96 header
->checksum
= HOST_TO_LE32(checksum
);
99 int main(int argc
, const char *argv
[])
101 const char *model_name
, *img_in
, *img_out
;
102 struct board_info
*board
;
103 int file_in
, file_out
;
105 size_t size_in
, size_out
;
109 fprintf(stderr
, "Usage: %s <model> <input> <output>\n", argv
[0]);
112 model_name
= argv
[1];
116 board
= find_board(model_name
);
118 fprintf(stderr
, "%s: Not supported model\n", model_name
);
122 if ((file_in
= open(img_in
, O_RDONLY
)) == -1)
123 err(EXIT_FAILURE
, "%s", img_in
);
125 if (fstat(file_in
, &stat_in
) == -1)
126 err(EXIT_FAILURE
, "%s", img_in
);
128 size_in
= stat_in
.st_size
;
129 size_out
= board
->payload_offset
+ size_in
;
131 if ((buffer
= malloc(size_out
)) == NULL
)
132 err(EXIT_FAILURE
, "malloc");
134 read(file_in
, buffer
+ board
->payload_offset
, size_in
);
137 memset(buffer
, 0, board
->payload_offset
);
139 make_header(board
, buffer
, size_in
);
141 if ((file_out
= creat(img_out
, 0644)) == -1)
142 err(EXIT_FAILURE
, "%s", img_out
);
143 write(file_out
, buffer
, size_out
);