firmware-utils: add tool to create zyxel images
authorVitaly Chekryzhev <13hakta@gmail.com>
Sat, 29 Oct 2016 12:26:58 +0000 (17:26 +0500)
committerMathias Kresin <dev@kresin.me>
Thu, 17 Nov 2016 19:01:21 +0000 (20:01 +0100)
Signed-off-by: Vitaly Chekryzhev <13hakta@gmail.com>
[moved to firmware-utils package]
[dropped the compiled binary]
Signed-off-by: Mathias Kresin <dev@kresin.me>
tools/firmware-utils/Makefile
tools/firmware-utils/src/zyimage.c [new file with mode: 0644]

index 1cfc8856b1757e195b6aacd8daf8c12e1983095c..456b7a39f5e17cee2625ac56d197e02a338473b8 100644 (file)
@@ -78,6 +78,7 @@ define Host/Compile
        $(call cc,mkmerakifw-old, -Wall)
        $(call cc,jcgimage, -lz -Wall)
        $(call cc,mkbuffaloimg, -Wall)
+       $(call cc,zyimage, -Wall)
 endef
 
 define Host/Install
diff --git a/tools/firmware-utils/src/zyimage.c b/tools/firmware-utils/src/zyimage.c
new file mode 100644 (file)
index 0000000..6aacf2f
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 Soul Trace <S-trace@list.ru>
+ *
+ * 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.
+ *
+ */
+
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 199309L /* getopt */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+
+#define szbuf 32768
+
+u_int32_t crc_tab[256];
+
+u_int32_t chksum_crc32 (FILE *f)
+{
+  register unsigned long crc;
+  unsigned long i, j;
+  char *buffer = malloc(szbuf);
+  char *buf;
+
+  crc = 0xFFFFFFFF;
+  while (!feof(f))
+  {
+    j = fread(buffer, 1, szbuf, f);
+    buf = buffer;
+    for (i = 0; i < j; i++)
+      crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *buf++) & 0xFF];
+  }
+  free(buffer);
+  return crc;
+}
+
+void chksum_crc32gentab ()
+{
+  unsigned long crc, poly;
+  int i, j;
+
+  poly = 0xEDB88320L;
+  for (i = 0; i < 256; i++)
+  {
+    crc = i;
+    for (j = 8; j > 0; j--)
+    {
+      if (crc & 1)
+        crc = (crc >> 1) ^ poly;
+      else
+        crc >>= 1;
+    }
+    crc_tab[i] = crc;
+  }
+}
+
+void usage(char *progname)
+{
+  printf("Usage: %s [ -v Version ] [ -d Device_ID ] <input file>\n", progname);
+  exit(1);
+}
+
+int main(int argc, char *argv[]) {
+  struct signature
+  {
+    const char magic[4];
+    unsigned int device_id;
+    char firmware_version[48];
+    unsigned int crc32;
+  }
+  sign =
+  {
+    { 'Z', 'N', 'B', 'G' },
+    1,
+    { "V.1.0.0(1.0.0)" },
+    0
+  };
+  FILE *f;
+  struct signature oldsign;
+  char *filename;
+  static const char *optString;
+  int opt;
+
+  if (argc < 1)
+    usage(argv[0]);
+
+  optString = "v:d:h";
+  opt = getopt( argc, argv, optString );
+  while( opt != -1 ) {
+    switch( opt ) {
+      case 'v':
+        if (optarg == NULL)
+          usage(argv[0]);
+        strncpy(sign.firmware_version, optarg, sizeof(sign.firmware_version)-1);
+       sign.firmware_version[sizeof(sign.firmware_version)-1]='\0'; /* Make sure that string is terminated correctly */
+        break;
+
+      case 'd':
+        sign.device_id = atoi(optarg);
+        if (sign.device_id == 0)
+          sign.device_id = (int)strtol(optarg, NULL, 16);
+        break;
+
+      case '?':
+      case 'h':
+        usage(argv[0]);
+        break;
+
+      default:
+        break;
+    }
+
+    opt = getopt( argc, argv, optString );
+  }
+
+  chksum_crc32gentab();
+
+  filename=argv[optind];
+  if (access(filename, W_OK) || access(filename, R_OK))
+  {
+    printf("Not open input file %s\n", filename);
+    exit(1);
+  }
+  f = fopen(argv[optind], "r+");
+  if (f != NULL)
+  {
+    fseek(f, sizeof(sign)*-1, SEEK_END);
+    fread(&oldsign, sizeof(oldsign), 1, f);
+
+    if (strncmp(oldsign.magic,"ZNBG", sizeof(oldsign.magic)) == 0 )
+    {
+      printf("Image is already signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", oldsign.device_id, oldsign.firmware_version, oldsign.crc32);
+      exit(0);
+    }
+
+    fseek(f, 0, SEEK_SET);
+    sign.crc32 = chksum_crc32(f);
+    fwrite(&sign, sizeof(sign), 1, f);
+    fclose(f);
+
+    printf("Image signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", sign.device_id, sign.firmware_version, sign.crc32);
+  }
+  return 0;
+}