$(call cc,mkrtn56uimg, -lz)
$(call cc,dgn3500sum)
$(call cc,edimax_fw_header, -Wall)
+ $(call cc,mkmerakifw sha1, -Wall)
endef
define Host/Install
*((uint32_t *) & b[0x18]) = 0x0L;
sum = crc32(b, 0x400);
- printf("CRC32 sum0 - (%x, %x, %x)\n", sum, sum0, 0x400);
+ printf("CRC32 sum0 - (%x, %lx, %x)\n", sum, sum0, 0x400);
if (EHDR)
lseek(fd, 0x20, SEEK_SET);
else
write(fd, &buf[0x18], 0x4);
sum = crc32(buf, l0);
- printf("CRC32 sum1 - (%x, %x, %x)\n", sum, sum1, l0);
+ printf("CRC32 sum1 - (%x, %lx, %x)\n", sum, sum1, l0);
if (EHDR)
lseek(fd, 0xC, SEEK_SET);
else
unsigned long sum2 = buf[-0x8] | ((uint32_t)buf[-0x7] << 8) | ((uint32_t)buf[-0x6] << 16) | ((uint32_t)buf[-0x5] << 24);
*((uint32_t *) & buf[-0x8]) = 0L;
sum = crc32(buf - 0x4, len - 0x4);
- printf("CRC32 sum2 - (%x, %x, %x)\n", sum, sum2,
+ printf("CRC32 sum2 - (%x, %lx, %lx)\n", sum, sum2,
len - 0x4);
lseek(fd, 0, SEEK_SET);
*((uint32_t *) & buf[-0x8]) = htonl(sum);
}
for (i = 0; i < bytes; i++) {
if (buf[i]) {
- fprintf(stderr, "Input TRX doesn't have last 64 B empty %s\n");
+ fprintf(stderr, "Input TRX doesn't have last 64 B empty %s\n", out_path);
err = -ENOSPC;
goto err;
}
bytes = sizeof(tail);
fseek(out, -bytes, SEEK_CUR);
if (fwrite(&tail, 1, bytes, out) != bytes) {
- fprintf(stderr, "Couldn't write %zu B to %s\n", bytes);
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
err = -EIO;
goto err;
}
hdr.crc32 = cpu_to_le32(crc32);
rewind(out);
if (fwrite(&hdr, 1, bytes, out) != bytes) {
- fprintf(stderr, "Couldn't write %zu B to %s\n", bytes);
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
err = -EIO;
goto err;
}
static char *product;
static char *version;
static int do_decrypt;
+static int offset;
void usage(int status)
{
" -p <product> set product name to <product>\n"
" -v <version> set version to <version>\n"
" -h show this screen\n"
+" -O Offset of encrypted data in file (decryption)\n"
);
exit(status);
ep.key = (unsigned char *) crypt_key;
ep.longstate = longstate;
- err = decrypt_buf(&ep, buf, src_len);
+ err = decrypt_buf(&ep, buf + offset, src_len - offset);
if (err) {
ERR("unable to decrypt '%s'", ifname);
goto out;
printf("Data len\t: %u\n", ep.datalen);
printf("Checksum\t: 0x%08x\n", ep.csum);
- err = write_buf_to_file(ofname, buf, ep.datalen);
+ err = write_buf_to_file(ofname, buf + offset, ep.datalen);
if (err) {
ERR("unable to write to file '%s'", ofname);
goto out;
while ( 1 ) {
int c;
- c = getopt(argc, argv, "adi:m:o:hlp:v:k:r:s:");
+ c = getopt(argc, argv, "adi:m:o:hlp:v:k:O:r:s:");
if (c == -1)
break;
case 's':
seed = strtoul(optarg, NULL, 16);
break;
+ case 'O':
+ offset = strtoul(optarg, NULL, 0);
+ break;
case 'h':
usage(EXIT_SUCCESS);
break;
uint32_t buffalo_csum(uint32_t csum, void *buf, unsigned long len)
{
- char *p = buf;
+ signed char *p = buf;
while (len--) {
int i;
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#define IMG_SIZE 0x3e0000
* for more details.
*
* Copyright (C) 2008 Axel Gembe <ago@bastart.eu.org>
- * Copyright (C) 2009-2010 Daniel Dickinson <librecmc@cshore.neomailbox.net>
+ * Copyright (C) 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <netinet/in.h>
+#include <inttypes.h>
#include "bcm_tag.h"
#include "imagetag_cmdline.h"
/* align the start if requested */
if (args->align_rootfs_flag)
rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff;
+ else
+ rootfsoff = (rootfsoff % 4) > 0 ? (((rootfsoff / 4) + 1) * 4) : rootfsoff;
/* align the end */
rootfsend = rootfsoff + getlen(rootfsfile);
sprintf(tag.totalLength, "%lu", imagelen);
if (args->cfe_given) {
- sprintf(tag.cfeAddress, "%lu", flash_start);
+ sprintf(tag.cfeAddress, "%" PRIu32, flash_start);
sprintf(tag.cfeLength, "%lu", cfelen);
} else {
/* We don't include CFE */
}
if (args->altinfo_given) {
- strncpy(&tag.information1[0], args->altinfo_arg, ALTTAGINFO_LEN);
+ strncpy(tag.information1, args->altinfo_arg, TAGINFO1_LEN);
}
if (args->second_image_flag_given) {
# Command line option parsing generator file for imagetag
# Supplied-To: gengetopt
#
-# Copyright 2010 Daniel Dickinson <librecmc@cshore.neomailbox.net>
+# Copyright 2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
const char *infile, *outfile;
FILE *in, *out;
- static const uint8_t buf[4096];
+ static uint8_t buf[4096];
size_t elems;
uint8_t properties;
/*
* mkbrncmdline.c - partially based on libreCMC's wndr3700.c
*
- * Copyright (C) 2011 Tobias Diedrich <ranma+librecmc@tdiedrich.de>
+ * Copyright (C) 2011 Tobias Diedrich <ranma+openwrt@tdiedrich.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
/*
- * mkbrnimg.c - partially based on libreCMC's wndr3700.c
+ * mkbrnimg.c - partially based on OpenWrt's wndr3700.c
*
- * Copyright (C) 2011 Tobias Diedrich <ranma+librecmc@tdiedrich.de>
+ * Copyright (C) 2011 Tobias Diedrich <ranma+openwrt@tdiedrich.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
// write padding
padded_len = ((len + sizeof(footer) + sizeof(padding) - 1) & ~(sizeof(padding) - 1)) - sizeof(footer);
- fprintf(stderr, "len=%08x padded_len=%08x\n", len, padded_len);
+ fprintf(stderr, "len=%08zx padded_len=%08zx\n", len, padded_len);
write(outfd, padding, padded_len - len);
// write footer
/*
*
* Copyright (C) 2007 OpenWrt.org
- * Copyright (C) 2007 Gabor Juhos <juhosg at librecmc.org>
+ * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
/* write padding data if neccesary */
padlen = desc->out_size - desc->file_size;
- DBG(1,"padding desc, length=%d", padlen);
+ DBG(1,"padding desc, length=%zu", padlen);
res = write_out_padding(outfile, padlen, desc->padc, &css);
desc->csum = csum_get(&css);
res = ERR_FATAL;
if (keep_invalid_images == 0) {
- WARN("generation of invalid images disabled", ofname);
+ WARN("generation of invalid images \"%s\" disabled", ofname);
goto out;
}
- WARN("generating invalid image", ofname);
+ WARN("generating invalid image: \"%s\"", ofname);
}
outfile = fopen(ofname, "w");
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", progname, ## __VA_ARGS__ \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", progname, ## __VA_ARGS__ \
, strerror(save)); \
} while (0)
/* write padding data if neccesary */
padlen = block->size_avail - block->file_size;
- DBG(1,"padding block, length=%d", padlen);
+ DBG(1,"padding block, length=%zu", padlen);
res = write_out_padding(outfile, padlen, block->padc, block->css);
return res;
res = ERR_FATAL;
if (keep_invalid_images == 0) {
- WARN("generation of invalid images disabled", ofname);
+ WARN("generation of invalid images \"%s\" disabled", ofname);
goto out;
}
- WARN("generating invalid image", ofname);
+ WARN("generating invalid image: \"%s\"", ofname);
}
outfile = fopen(ofname, "w");
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
}
d = &im.parts[im.part_count];
- t = sscanf(part_desc, "%15[0-9a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%256s",
+ t = sscanf(part_desc, "%15[-0-9a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%256s",
d->partition_name,
offset,
length,
* gcc -lcrypto hlkcrypt.c -o hlkcrypt
*/
+#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
--- /dev/null
+/*
+ * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com>
+ *
+ * The format of the header this tool generates was first documented by
+ * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the
+ * same purpose. I have created this reimplementation at his request. The
+ * original script can be found at:
+ * <https://github.com/riptidewave93/meraki-partbuilder>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include "sha1.h"
+
+#define PADDING_BYTE 0xff
+
+#define HDR_LENGTH 0x00000400
+#define HDR_OFF_MAGIC1 0
+#define HDR_OFF_HDRLEN 4
+#define HDR_OFF_IMAGELEN 8
+#define HDR_OFF_CHECKSUM 12
+#define HDR_OFF_MAGIC2 32
+#define HDR_OFF_FILLER 36
+#define HDR_OFF_STATICHASH 40
+
+struct board_info {
+ uint32_t magic;
+ uint32_t imagelen;
+ unsigned char statichash[20];
+ char *id;
+ char *description;
+};
+
+/*
+ * Globals
+ */
+static char *progname;
+
+static char *board_id;
+static const struct board_info *board;
+
+static const struct board_info boards[] = {
+ {
+ .id = "mr18",
+ .description = "Meraki MR18 Access Point",
+ .magic = 0x8e73ed8a,
+ .imagelen = 0x00800000,
+ .statichash = {0xda, 0x39, 0xa3, 0xee, 0x5e,
+ 0x6b, 0x4b, 0x0d, 0x32, 0x55,
+ 0xbf, 0xef, 0x95, 0x60, 0x18,
+ 0x90, 0xaf, 0xd8, 0x07, 0x09},
+ }, {
+ /* terminating entry */
+ }
+};
+
+/*
+ * Message macros
+ */
+#define ERR(fmt, ...) do { \
+ fflush(0); \
+ fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ progname, ## __VA_ARGS__); \
+} while (0)
+
+#define ERRS(fmt, ...) do { \
+ int save = errno; \
+ fflush(0); \
+ fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+static const struct board_info *find_board(const char *id)
+{
+ const struct board_info *ret;
+ const struct board_info *board;
+
+ ret = NULL;
+ for (board = boards; board->id != NULL; board++) {
+ if (strcasecmp(id, board->id) == 0) {
+ ret = board;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+ const struct board_info *board;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -B <board> create image for the board specified with <board>\n"
+" -i <file> read kernel image from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -s strip padding from the end of the image\n"
+" -h show this screen\n"
+ );
+
+ fprintf(stream, "\nBoards:\n");
+ for (board = boards; board->id != NULL; board++)
+ fprintf(stream, " %-16s%s\n", board->id, board->description);
+
+ exit(status);
+}
+
+void writel(unsigned char *buf, size_t offset, uint32_t value)
+{
+ value = htonl(value);
+ memcpy(buf + offset, &value, sizeof(uint32_t));
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ long klen;
+ size_t kspace;
+ unsigned char *kernel;
+ size_t buflen;
+ unsigned char *buf;
+ bool strip_padding = false;
+ char *ofname = NULL, *ifname = NULL;
+ FILE *out, *in;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "B:i:o:sh");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ board_id = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 's':
+ strip_padding = true;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (board_id == NULL) {
+ ERR("no board specified");
+ goto err;
+ }
+
+ board = find_board(board_id);
+ if (board == NULL) {
+ ERR("unknown board \"%s\"", board_id);
+ goto err;
+ }
+
+ if (ifname == NULL) {
+ ERR("no input file specified");
+ goto err;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ goto err;
+ }
+
+ in = fopen(ifname, "r");
+ if (in == NULL) {
+ ERRS("could not open \"%s\" for reading: %s", ifname);
+ goto err;
+ }
+
+ buflen = board->imagelen;
+ kspace = buflen - HDR_LENGTH;
+
+ /* Get kernel length */
+ fseek(in, 0, SEEK_END);
+ klen = ftell(in);
+ rewind(in);
+
+ if (klen > kspace) {
+ ERR("file \"%s\" is too big - max size: 0x%08lX\n",
+ ifname, kspace);
+ goto err_close_in;
+ }
+
+ /* If requested, resize buffer to remove padding */
+ if (strip_padding)
+ buflen = klen + HDR_LENGTH;
+
+ /* Allocate and initialize buffer for final image */
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ ERRS("no memory for buffer: %s\n");
+ goto err_close_in;
+ }
+ memset(buf, PADDING_BYTE, buflen);
+
+ /* Load kernel */
+ kernel = buf + HDR_LENGTH;
+ fread(kernel, klen, 1, in);
+
+ /* Write magic values and filler */
+ writel(buf, HDR_OFF_MAGIC1, board->magic);
+ writel(buf, HDR_OFF_MAGIC2, board->magic);
+ writel(buf, HDR_OFF_FILLER, 0);
+
+ /* Write header and image length */
+ writel(buf, HDR_OFF_HDRLEN, HDR_LENGTH);
+ writel(buf, HDR_OFF_IMAGELEN, klen);
+
+ /* Write checksum and static hash */
+ sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM);
+ memcpy(buf + HDR_OFF_STATICHASH, board->statichash, 20);
+
+ /* Save finished image */
+ out = fopen(ofname, "w");
+ if (out == NULL) {
+ ERRS("could not open \"%s\" for writing: %s", ofname);
+ goto err_free;
+ }
+ fwrite(buf, buflen, 1, out);
+
+ ret = EXIT_SUCCESS;
+
+ fclose(out);
+
+err_free:
+ free(buf);
+
+err_close_in:
+ fclose(in);
+
+err:
+ return ret;
+}
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
#define HEADER_VERSION_V1 0x01000000
-#define HWID_ANTMINER_S1 0x04440001
-#define HWID_ANTMINER_S3 0x04440003
+#define HEADER_VERSION_V2 0x02000000
+#define HWID_ANTMINER_S1 0x04440101
+#define HWID_ANTMINER_S3 0x04440301
#define HWID_GL_INET_V1 0x08000001
#define HWID_GS_OOLITE_V1 0x3C000101
#define HWID_ONION_OMEGA 0x04700001
static char *vendor = "TP-LINK Technologies";
static char *version = "ver. 1.0";
static char *fw_ver = "0.0.0";
+static uint32_t hdr_ver = HEADER_VERSION_V1;
static char *board_id;
static struct board_info *board;
static uint32_t hw_id;
static char *opt_hw_rev;
static uint32_t hw_rev;
+static uint32_t opt_hdr_ver = 1;
static int fw_ver_lo;
static int fw_ver_mid;
static int fw_ver_hi;
.hw_id = HWID_ANTMINER_S1,
.hw_rev = 1,
.layout_id = "8Mlzma",
+ }, {
+ .id = "ANTMINER-S3",
+ .hw_id = HWID_ANTMINER_S3,
+ .hw_rev = 1,
+ .layout_id = "8Mlzma",
}, {
/* terminating entry */
}
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
" -N <vendor> set image vendor to <vendor>\n"
" -V <version> set image version to <version>\n"
" -v <version> set firmware version to <version>\n"
+" -m <version> set header version to <version>\n"
" -i <file> inspect given firmware file <file>\n"
" -x extract kernel and rootfs while inspecting (requires -i)\n"
" -X <size> reserve <size> bytes in the firmware image (hexval prefixed with 0x)\n"
static int check_options(void)
{
int ret;
+ int exceed_bytes;
if (inspect_info.file_name) {
ret = get_file_stat(&inspect_info);
kernel_len = kernel_info.file_size;
if (combined) {
- if (kernel_info.file_size >
- fw_max_len - sizeof(struct fw_header)) {
+ exceed_bytes = kernel_info.file_size - (fw_max_len - sizeof(struct fw_header));
+ if (exceed_bytes > 0) {
if (!ignore_size) {
- ERR("kernel image is too big");
+ ERR("kernel image is too big by %i bytes", exceed_bytes);
return -1;
}
layout->fw_max_len = sizeof(struct fw_header) +
DBG("kernel length aligned to %u", kernel_len);
- if (kernel_len + rootfs_info.file_size >
- fw_max_len - sizeof(struct fw_header)) {
- ERR("images are too big");
+ exceed_bytes = kernel_len + rootfs_info.file_size - (fw_max_len - sizeof(struct fw_header));
+ if (exceed_bytes > 0) {
+ ERR("images are too big by %i bytes", exceed_bytes);
return -1;
}
} else {
- if (kernel_info.file_size >
- rootfs_ofs - sizeof(struct fw_header)) {
- ERR("kernel image is too big");
+ exceed_bytes = kernel_info.file_size - (rootfs_ofs - sizeof(struct fw_header));
+ if (exceed_bytes > 0) {
+ ERR("kernel image is too big by %i bytes", exceed_bytes);
return -1;
}
- if (rootfs_info.file_size >
- (fw_max_len - rootfs_ofs)) {
- ERR("rootfs image is too big");
+ exceed_bytes = rootfs_info.file_size - (fw_max_len - rootfs_ofs);
+ if (exceed_bytes > 0) {
+ ERR("rootfs image is too big by %i bytes", exceed_bytes);
return -1;
}
}
return -1;
}
+ if (opt_hdr_ver == 1) {
+ hdr_ver = HEADER_VERSION_V1;
+ } else if (opt_hdr_ver == 2) {
+ hdr_ver = HEADER_VERSION_V2;
+ } else {
+ ERR("invalid header version '%u'", opt_hdr_ver);
+ return -1;
+ }
+
return 0;
}
memset(hdr, 0, sizeof(struct fw_header));
- hdr->version = htonl(HEADER_VERSION_V1);
+ hdr->version = htonl(hdr_ver);
strncpy(hdr->vendor_name, vendor, sizeof(hdr->vendor_name));
strncpy(hdr->fw_version, version, sizeof(hdr->fw_version));
hdr->hw_id = htonl(hw_id);
inspect_fw_pstr("File name", inspect_info.file_name);
inspect_fw_phexdec("File size", inspect_info.file_size);
- if (ntohl(hdr->version) != HEADER_VERSION_V1) {
- ERR("file does not seem to have V1 header!\n");
+ if ((ntohl(hdr->version) != HEADER_VERSION_V1) &&
+ (ntohl(hdr->version) != HEADER_VERSION_V2)) {
+ ERR("file does not seem to have V1/V2 header!\n");
goto out_free_buf;
}
while ( 1 ) {
int c;
- c = getopt(argc, argv, "a:B:H:E:F:L:V:N:W:ci:k:r:R:o:xX:hsSjv:");
+ c = getopt(argc, argv, "a:B:H:E:F:L:m:V:N:W:ci:k:r:R:o:xX:hsSjv:");
if (c == -1)
break;
case 'L':
sscanf(optarg, "0x%x", &kernel_la);
break;
+ case 'm':
+ sscanf(optarg, "%u", &opt_hdr_ver);
+ break;
case 'V':
version = optarg;
break;
.hw_id = 0x89700001,
.hw_rev = 1,
.layout_id = "8Mltq",
+ }, {
+ .id = "TD-W8980v1",
+ .hw_id = 0x89800001,
+ .hw_rev = 14,
+ .layout_id = "8Mltq",
}, {
.id = "ArcherC20i",
.hw_id = 0xc2000001,
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
/*
*
* Copyright (C) 2007-2008 OpenWrt.org
- * Copyright (C) 2007-2008 Gabor Juhos <juhosg at librecmc.org>
+ * Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org>
*
* This code was based on the information of the ZyXEL's firmware
* image format written by Kolja Waschk, can be found at:
#if defined(__CYGWIN__)
# include <byteswap.h>
#endif
+#include <inttypes.h>
#include "zynos.h"
FILE *f;
int res;
- DBG(2, "writing out file, name=%s, len=%d",
+ DBG(2, "writing out file, name=%s, len=%zu",
name, len);
errno = 0;
uint32_t avail;
int i, res;
- DBG(1,"calculating block offsets, starting with %lu",
+ DBG(1,"calculating block offsets, starting with %" PRIu32,
*offset);
res = 0;
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
{
printf("SEAMA ==========================================\n");
printf(" magic : %08x\n", ntohl(shdr.magic));
- printf(" meta size : %d bytes\n", msize);
+ printf(" meta size : %zu bytes\n", msize);
for (i=0; i<msize; i+=(strlen((const char *)&buf[i])+1))
printf(" meta data : %s\n", &buf[i]);
- printf(" image size : %d bytes\n", isize);
+ printf(" image size : %zu bytes\n", isize);
}
/* verify checksum */
fread(buf, sizeof(char), msize, ifh);
if (match_meta((const char *)buf, msize))
{
- printf("SEAMA: found image @ '%s', image size: %d\n", o_images[i], isize);
+ printf("SEAMA: found image @ '%s', image size: %zu\n", o_images[i], isize);
/* open output file */
ofh = fopen(output, "w");
if (!ofh) printf("SEAMA: unable to open '%s' for writting.\n",output);
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
return(1);
}
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
debug = TRUE;
debug = FALSE;
/** Vendor information for CPE210/220/510/520 */
-static const unsigned char cpe510_vendor[] = "\x00\x00\x00\x1f""CPE510(TP-LINK|UN|N300-5):1.0\r\n";
+static const char cpe510_vendor[] = "CPE510(TP-LINK|UN|N300-5):1.0\r\n";
/**
/**
The support list for CPE210/220/510/520
-
- The stock images also contain strings for two more devices: BS510 and BS210.
- At the moment, there exists no public information about these devices.
*/
-static const unsigned char cpe510_support_list[] =
- "\x00\x00\x00\xc8\x00\x00\x00\x00"
+static const char cpe510_support_list[] =
"SupportList:\r\n"
"CPE510(TP-LINK|UN|N300-5):1.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
"CPE520(TP-LINK|UN|N300-5):1.0\r\n"
+ "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
"CPE210(TP-LINK|UN|N300-2):1.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
"CPE220(TP-LINK|UN|N300-2):1.0\r\n"
- "\r\n\xff";
+ "CPE220(TP-LINK|UN|N300-2):1.1\r\n";
#define error(_ret, _errno, _str, ...) \
do { \
} while (0)
+/** Stores a uint32 as big endian */
+static inline void put32(uint8_t *buf, uint32_t val) {
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+}
+
/** Allocates a new image partition */
-struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
+static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
struct image_partition_entry entry = {name, len, malloc(len)};
if (!entry.data)
error(1, errno, "malloc");
}
/** Frees an image partition */
-void free_image_partition(struct image_partition_entry entry) {
+static void free_image_partition(struct image_partition_entry entry) {
free(entry.data);
}
/** Generates the partition-table partition */
-struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
+static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
char *s = (char *)entry.data, *end = (char *)(s+entry.size);
/** Generates the soft-version partition */
-struct image_partition_entry make_soft_version(uint32_t rev) {
+static struct image_partition_entry make_soft_version(uint32_t rev) {
struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version));
struct soft_version *s = (struct soft_version *)entry.data;
}
/** Generates the support-list partition */
-struct image_partition_entry make_support_list(const unsigned char *support_list, size_t len) {
- struct image_partition_entry entry = alloc_image_partition("support-list", len);
- memcpy(entry.data, support_list, len);
+static struct image_partition_entry make_support_list(const char *support_list) {
+ size_t len = strlen(support_list);
+ struct image_partition_entry entry = alloc_image_partition("support-list", len + 9);
+
+ put32(entry.data, len);
+ memset(entry.data+4, 0, 4);
+ memcpy(entry.data+8, support_list, len);
+ entry.data[len+8] = '\xff';
+
return entry;
}
/** Creates a new image partition with an arbitrary name from a file */
-struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof) {
+static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof) {
struct stat statbuf;
if (stat(filename, &statbuf) < 0)
I think partition-table must be the first partition in the firmware image.
*/
-void put_partitions(uint8_t *buffer, const struct image_partition_entry *parts) {
+static void put_partitions(uint8_t *buffer, const struct image_partition_entry *parts) {
size_t i;
char *image_pt = (char *)buffer, *end = image_pt + 0x800;
}
/** Generates and writes the image MD5 checksum */
-void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
+static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
MD5_CTX ctx;
MD5_Init(&ctx);
----------- -----
0000-0003 Image size (4 bytes, big endian)
0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
- 0014-1013 Vendor information (4096 bytes, padded with 0xff; there seem to be older
+ 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
+ 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
(VxWorks-based) TP-LINK devices which use a smaller vendor information block)
1014-1813 Image partition table (2048 bytes, padded with 0xff)
1814-xxxx Firmware partitions
*/
-void * generate_factory_image(const unsigned char *vendor, size_t vendor_len, const struct image_partition_entry *parts, size_t *len) {
+static void * generate_factory_image(const char *vendor, const struct image_partition_entry *parts, size_t *len) {
*len = 0x1814;
size_t i;
if (!image)
error(1, errno, "malloc");
- image[0] = *len >> 24;
- image[1] = *len >> 16;
- image[2] = *len >> 8;
- image[3] = *len;
+ put32(image, *len);
- memcpy(image+0x14, vendor, vendor_len);
- memset(image+0x14+vendor_len, 0xff, 4096-vendor_len);
+ size_t vendor_len = strlen(vendor);
+ put32(image+0x14, vendor_len);
+ memcpy(image+0x18, vendor, vendor_len);
+ memset(image+0x18+vendor_len, 0xff, 4092-vendor_len);
put_partitions(image + 0x1014, parts);
put_md5(image+0x04, image+0x14, *len-0x14);
should be generalized when TP-LINK starts building its safeloader into hardware with
different flash layouts.
*/
-void * generate_sysupgrade_image(const struct flash_partition_entry *flash_parts, const struct image_partition_entry *image_parts, size_t *len) {
+static void * generate_sysupgrade_image(const struct flash_partition_entry *flash_parts, const struct image_partition_entry *image_parts, size_t *len) {
const struct flash_partition_entry *flash_os_image = &flash_parts[5];
const struct flash_partition_entry *flash_soft_version = &flash_parts[6];
const struct flash_partition_entry *flash_support_list = &flash_parts[7];
parts[0] = make_partition_table(cpe510_partitions);
parts[1] = make_soft_version(rev);
- parts[2] = make_support_list(cpe510_support_list, sizeof(cpe510_support_list)-1);
+ parts[2] = make_support_list(cpe510_support_list);
parts[3] = read_file("os-image", kernel_image, false);
parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof);
if (sysupgrade)
image = generate_sysupgrade_image(cpe510_partitions, parts, &len);
else
- image = generate_factory_image(cpe510_vendor, sizeof(cpe510_vendor)-1, parts, &len);
+ image = generate_factory_image(cpe510_vendor, parts, &len);
FILE *file = fopen(output, "wb");
if (!file)
/** Usage output */
-void usage(const char *argv0) {
+static void usage(const char *argv0) {
fprintf(stderr,
"Usage: %s [OPTIONS...]\n"
"\n"
*
* Author: Sandeep Mistry
*/
+#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include "cyg_crc.h"
-// https://dev.librecmc.org/browser/trunk/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c
+// https://dev.openwrt.org/browser/trunk/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c
static uint32_t crctab[257] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
/*
*
* Copyright (C) 2007-2008 OpenWrt.org
- * Copyright (C) 2007-2008 Gabor Juhos <juhosg at librecmc.org>
+ * Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org>
*
* This code was based on the information of the ZyXEL's firmware
* image format written by Kolja Waschk, can be found at:
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>