• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/iptime-crc32.c

  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 = "ax2004m", .payload_offset = 0x38 },
 57         { .model = "ax3000m", .payload_offset = 0x38 },
 58         { .model = "ax3000q", .payload_offset = 0x38 },
 59         { .model = "ax6000m", .payload_offset = 0x38 },
 60         { .model = "ax7800m", .payload_offset = 0x38 },
 61         { .model = "ax8004m", .payload_offset = 0x38 },
 62         { .model = "ax3ksm", .payload_offset = 0x38 },
 63         { /* sentinel */ }
 64 };
 65 
 66 struct board_info *find_board(const char *model)
 67 {
 68         struct board_info *ret = NULL;
 69         struct board_info *board;
 70 
 71         for (board = boards; board->model != NULL; board++) {
 72                 if (strcmp(model, board->model) == 0) {
 73                         ret = board;
 74                         break;
 75                 }
 76         }
 77 
 78         return ret;
 79 }
 80 
 81 uint32_t make_checksum(struct fw_header *header, uint8_t *payload, int size)
 82 {
 83         cyg_uint32 checksum;
 84 
 85         /* get CRC of header */
 86         checksum = cyg_crc32_accumulate(~0L, header, sizeof(*header));
 87 
 88         /* get CRC of payload buffer with header CRC as initial value */
 89         return (uint32_t)cyg_crc32_accumulate(checksum, payload, size);
 90 }
 91 
 92 void make_header(struct board_info *board, uint8_t *buffer, size_t img_size)
 93 {
 94         struct fw_header *header = (struct fw_header *)buffer;
 95         uint32_t checksum;
 96 
 97         strncpy((char *)header->model, board->model, sizeof(header->model)-1);
 98         strncpy((char *)header->version, FW_VERSION, sizeof(header->version)-1);
 99         header->size = HOST_TO_LE32(img_size);
100         checksum = make_checksum(header, buffer + board->payload_offset, img_size);
101         header->checksum = HOST_TO_LE32(checksum);
102 }
103 
104 int main(int argc, const char *argv[])
105 {
106         const char *model_name, *img_in, *img_out;
107         struct board_info *board;
108         int file_in, file_out;
109         struct stat stat_in;
110         size_t size_in, size_out;
111         uint8_t *buffer;
112 
113         if (argc != 4) {
114                 fprintf(stderr, "Usage: %s <model> <input> <output>\n", argv[0]);
115                 return EXIT_FAILURE;
116         }
117         model_name = argv[1];
118         img_in = argv[2];
119         img_out = argv[3];
120 
121         board = find_board(model_name);
122         if (board == NULL) {
123                 fprintf(stderr, "%s: Not supported model\n", model_name);
124                 return EXIT_FAILURE;
125         }
126 
127         if ((file_in = open(img_in, O_RDONLY)) == -1)
128                 err(EXIT_FAILURE, "%s", img_in);
129 
130         if (fstat(file_in, &stat_in) == -1)
131                 err(EXIT_FAILURE, "%s", img_in);
132 
133         size_in = stat_in.st_size;
134         size_out = board->payload_offset + size_in;
135 
136         if ((buffer = malloc(size_out)) == NULL)
137                 err(EXIT_FAILURE, "malloc");
138 
139         read(file_in, buffer + board->payload_offset, size_in);
140         close(file_in);
141 
142         memset(buffer, 0, board->payload_offset);
143 
144         make_header(board, buffer, size_in);
145 
146         if ((file_out = creat(img_out, 0644)) == -1)
147                 err(EXIT_FAILURE, "%s", img_out);
148         write(file_out, buffer, size_out);
149         close(file_out);
150 
151         free(buffer);
152 
153         return EXIT_SUCCESS;
154 }
155 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt