1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2021 Sungbo Eo <mans0n@gorani.run> 4 * 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> 8 * 9 * Checksum algorithm is derived from add_iptime_fw_header.c 10 * Copyright (C) 2020 Jaehoon You <teslamint@gmail.com> 11 */ 12 13 #include <byteswap.h> 14 #include <endian.h> 15 #include <err.h> 16 #include <errno.h> 17 #include <fcntl.h> 18 #include <stdint.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/stat.h> 23 #include <unistd.h> 24 25 #include "cyg_crc.h" 26 27 #if !defined(__BYTE_ORDER) 28 #error "Unknown byte order" 29 #endif 30 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) 35 #else 36 #error "Unsupported endianness" 37 #endif 38 39 #define FW_VERSION "00_000" 40 41 struct fw_header { 42 uint8_t model[8]; 43 uint8_t version[8]; 44 uint8_t reserved[32]; 45 uint32_t size; 46 uint32_t checksum; 47 } __attribute__ ((packed)); 48 49 struct board_info { 50 const char *model; 51 size_t payload_offset; 52 }; 53 54 struct board_info boards[] = { 55 { .model = "a6004mx", .payload_offset = 0x800 }, 56 { .model = "ax2002m", .payload_offset = 0x38 }, 57 { .model = "ax2004m", .payload_offset = 0x38 }, 58 { .model = "ax3000m", .payload_offset = 0x38 }, 59 { .model = "ax3000q", .payload_offset = 0x38 }, 60 { .model = "ax6000m", .payload_offset = 0x38 }, 61 { .model = "ax7800m", .payload_offset = 0x38 }, 62 { .model = "ax8004m", .payload_offset = 0x38 }, 63 { .model = "ax3kse", .payload_offset = 0x38 }, 64 { .model = "ax3ksm", .payload_offset = 0x38 }, 65 { /* sentinel */ } 66 }; 67 68 struct board_info *find_board(const char *model) 69 { 70 struct board_info *ret = NULL; 71 struct board_info *board; 72 73 for (board = boards; board->model != NULL; board++) { 74 if (strcmp(model, board->model) == 0) { 75 ret = board; 76 break; 77 } 78 } 79 80 return ret; 81 } 82 83 uint32_t make_checksum(struct fw_header *header, uint8_t *payload, int size) 84 { 85 cyg_uint32 checksum; 86 87 /* get CRC of header */ 88 checksum = cyg_crc32_accumulate(~0L, header, sizeof(*header)); 89 90 /* get CRC of payload buffer with header CRC as initial value */ 91 return (uint32_t)cyg_crc32_accumulate(checksum, payload, size); 92 } 93 94 void make_header(struct board_info *board, uint8_t *buffer, size_t img_size) 95 { 96 struct fw_header *header = (struct fw_header *)buffer; 97 uint32_t checksum; 98 99 strncpy((char *)header->model, board->model, sizeof(header->model)-1); 100 strncpy((char *)header->version, FW_VERSION, sizeof(header->version)-1); 101 header->size = HOST_TO_LE32(img_size); 102 checksum = make_checksum(header, buffer + board->payload_offset, img_size); 103 header->checksum = HOST_TO_LE32(checksum); 104 } 105 106 int main(int argc, const char *argv[]) 107 { 108 const char *model_name, *img_in, *img_out; 109 struct board_info *board; 110 int file_in, file_out; 111 struct stat stat_in; 112 size_t size_in, size_out; 113 uint8_t *buffer; 114 115 if (argc != 4) { 116 fprintf(stderr, "Usage: %s <model> <input> <output>\n", argv[0]); 117 return EXIT_FAILURE; 118 } 119 model_name = argv[1]; 120 img_in = argv[2]; 121 img_out = argv[3]; 122 123 board = find_board(model_name); 124 if (board == NULL) { 125 fprintf(stderr, "%s: Not supported model\n", model_name); 126 return EXIT_FAILURE; 127 } 128 129 if ((file_in = open(img_in, O_RDONLY)) == -1) 130 err(EXIT_FAILURE, "%s", img_in); 131 132 if (fstat(file_in, &stat_in) == -1) 133 err(EXIT_FAILURE, "%s", img_in); 134 135 size_in = stat_in.st_size; 136 size_out = board->payload_offset + size_in; 137 138 if ((buffer = malloc(size_out)) == NULL) 139 err(EXIT_FAILURE, "malloc"); 140 141 read(file_in, buffer + board->payload_offset, size_in); 142 close(file_in); 143 144 memset(buffer, 0, board->payload_offset); 145 146 make_header(board, buffer, size_in); 147 148 if ((file_out = creat(img_out, 0644)) == -1) 149 err(EXIT_FAILURE, "%s", img_out); 150 write(file_out, buffer, size_out); 151 close(file_out); 152 153 free(buffer); 154 155 return EXIT_SUCCESS; 156 } 157
This page was automatically generated by LXR 0.3.1. • OpenWrt