📄 mkcasfw.c
字号:
/* * $Id: mkcasfw.c 11527 2008-06-17 15:05:53Z juhosg $ * * Copyright (C) 2007 OpenWrt.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 * by the Free Software Foundation. * */#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <unistd.h> /* for unlink() */#include <libgen.h>#include <getopt.h> /* for getopt() */#include <stdarg.h>#include <errno.h>#include <sys/stat.h>#include <endian.h> /* for __BYTE_ORDER */#if defined(__CYGWIN__)# include <byteswap.h>#endif#if (__BYTE_ORDER == __LITTLE_ENDIAN)# define HOST_TO_LE16(x) (x)# define HOST_TO_LE32(x) (x)# define LE16_TO_HOST(x) (x)# define LE32_TO_HOST(x) (x)#else# define HOST_TO_LE16(x) bswap_16(x)# define HOST_TO_LE32(x) bswap_32(x)# define LE16_TO_HOST(x) bswap_16(x)# define LE32_TO_HOST(x) bswap_32(x)#endif#define MAX_NUM_BLOCKS 2#define MAX_ARG_COUNT 32#define MAX_ARG_LEN 1024#define FILE_BUF_LEN (16*1024)#define DEFAULT_PADC 0xFF#define DEFAULT_BLOCK_ALIGN 0x10000U#define CSUM_TYPE_NONE 0#define CSUM_TYPE_8 1#define CSUM_TYPE_16 2#define CSUM_TYPE_32 3struct csum_state{ int size; uint32_t val; uint32_t tmp; int odd;};struct image_desc { int need_file; char *file_name; /* name of the file */ uint32_t file_size; /* length of the file */ uint32_t csum; uint32_t out_size; uint8_t padc;};struct fwhdr_nfs { uint32_t type; uint32_t kernel_offs; uint32_t kernel_size; uint32_t fs_offs; uint32_t fs_size; uint32_t kernel_csum; uint32_t fs_csum; uint32_t id;} __attribute__ ((packed));struct fwhdr_cas { uint32_t type; uint32_t kernel_offs; uint32_t kernel_size; uint32_t id; uint32_t kernel_csum; uint32_t magic1; uint32_t magic2; uint32_t magic3;} __attribute__ ((packed));union file_hdr { struct fwhdr_cas cas; struct fwhdr_nfs nfs;};struct board_info { char *model; char *name; int header_type; uint32_t id; uint32_t max_kernel_size; uint32_t max_fs_size;};#define HEADER_TYPE_NFS 0#define HEADER_TYPE_CAS 1#define KERNEL_SIZE_CAS (61*64*1024)#define KERNEL_SIZE_NFS (52*64*1024)#define FS_SIZE_NFS (9*64*1024)#define CAS_MAGIC1 0x5241AA55#define CAS_MAGIC2 0x524F4741#define CAS_MAGIC3 0xD3F22D4E/* Cellvision/SparkLAN products */#define MODEL_CAS_630 0x01000000#define MODEL_CAS_630W 0x01000000#define MODEL_CAS_670 0x01000000#define MODEL_CAS_670W 0x01000000#define MODEL_NFS_101U 0x01000000#define MODEL_NFS_101WU 0x01000003#define MODEL_NFS_202U 0x01000001#define MODEL_NFS_202WU 0x01000002/* Corega products */#define MODEL_CG_NSADP 0x01000020 /* NFS-101U */#define MODEL_CG_NSADPCR 0x01000021 /* NFS-202U *//* D-Link products */#define MODEL_DCS_950 0x01010102 /* CAS-630 */#define MODEL_DCS_950G 0x01020102 /* CAS-630W */#define MODEL_DNS_120 0x01000030 /* NFS-101U */#define MODEL_DNS_G120 0x01000032 /* NFS-101WU *//* Digitus products */#define MODEL_DN_16021 MODEL_CAS_630#define MODEL_DN_16022 MODEL_CAS_630W#define MODEL_DN_16030 MODEL_CAS_670#define MODEL_DN_16031 MODEL_CAS_670W#define MODEL_DN_7013 MODEL_NFS_101U/* Lobos products */#define MODEL_LB_SS01TXU 0x00000000/* Neu-Fusion products *//* Ovislink products */#define MODEL_MU_5000FS 0x01000040 /* NFS-101U */#define MODEL_WL_5420CAM 0x020B0101 /* CAS-630W? */#define MODEL_WL_5460CAM 0x020B0001 /* CAS-670W *//* Repotec products *//* Sitecom products */#define MODEL_LN_350 /* unknown */#define MODEL_LN_403 0x01020402#define MODEL_WL_401 0x01010402/* Surecom products */#define MODEL_EP_4001_MM 0x01030A02 /* CAS-630 */#define MODEL_EP_4002_MM 0x01020A02 /* CAS-630W */#define MODEL_EP_4011_MM 0x01010A02 /* CAS-670 */#define MODEL_EP_4012_MM 0x01000A02 /* CAS-670W */#define MODEL_EP_9812_U /* unknown *//* Trendnet products */#define MODEL_TN_U100 0x01000081 /* NFS-101U */#define MODEL_TN_U200 0x01000081 /* NFS-202U *//* * Globals */char *progname;char *ofname;int verblevel;int keep_invalid_images;int invalid_causes_error = 1;union file_hdr header;struct image_desc kernel_image;struct image_desc fs_image;struct board_info *board = NULL;#define BOARD(m, n, i, ks, fs, h) { \ .model = (m), \ .name = (n), \ .id = (i), \ .max_kernel_size = (ks), \ .max_fs_size = (fs), \ .header_type = (h) \ }#define BOARD_CAS(m,n,i) \ BOARD(m, n, i, KERNEL_SIZE_CAS, 0, HEADER_TYPE_CAS)#define BOARD_NFS(m,n,i) \ BOARD(m, n, i, KERNEL_SIZE_NFS, FS_SIZE_NFS, HEADER_TYPE_NFS)static struct board_info boards[] = { /* Cellvision/Sparklan products */ BOARD_CAS("CAS-630", "Cellvision CAS-630", MODEL_CAS_630), BOARD_CAS("CAS-630W", "Cellvision CAS-630W", MODEL_CAS_630W), BOARD_CAS("CAS-670", "Cellvision CAS-670", MODEL_CAS_670), BOARD_CAS("CAS-670W", "Cellvision CAS-670W", MODEL_CAS_670W), BOARD_NFS("NFS-101U", "Cellvision NFS-101U", MODEL_NFS_101U), BOARD_NFS("NFS-101WU", "Cellvision NFS-101WU", MODEL_NFS_101WU), BOARD_NFS("NFS-202U", "Cellvision NFS-202U", MODEL_NFS_202U), BOARD_NFS("NFS-202WU", "Cellvision NFS-202WU", MODEL_NFS_202WU), /* Corega products */ BOARD_NFS("CG-NSADP", "Corega CG-NSADP", MODEL_CG_NSADP), BOARD_NFS("CG-NSADPCR", "Corega CG-NSADPCR", MODEL_CG_NSADPCR), /* D-Link products */ BOARD_CAS("DCS-950", "D-Link DCS-950", MODEL_DCS_950), BOARD_CAS("DCS-950G", "D-Link DCS-950G", MODEL_DCS_950G), BOARD_NFS("DNS-120", "D-Link DNS-120", MODEL_DNS_120), BOARD_NFS("DNS-G120", "D-Link DNS-G120", MODEL_DNS_G120), /* Digitus products */ BOARD_NFS("DN-7013", "Digitus DN-7013", MODEL_DN_7013), /* Lobos products */ BOARD_NFS("LB-SS01TXU", "Lobos LB-SS01TXU", MODEL_LB_SS01TXU), /* Ovislink products */ BOARD_NFS("MU-5000FS", "Ovislink MU-5000FS", MODEL_MU_5000FS), BOARD_CAS("WL-5420CAM", "Ovislink WL-5420 CAM", MODEL_WL_5420CAM), BOARD_CAS("WL-5460CAM", "Ovislink WL-5460 CAM", MODEL_WL_5460CAM), /* Sitecom products */ BOARD_CAS("LN-403", "Sitecom LN-403", MODEL_LN_403), BOARD_CAS("WL-401", "Sitecom WL-401", MODEL_WL_401), /* Surecom products */ BOARD_CAS("EP-4001-MM", "Surecom EP-4001-MM", MODEL_EP_4001_MM), BOARD_CAS("EP-4002-MM", "Surecom EP-4002-MM", MODEL_EP_4002_MM), BOARD_CAS("EP-4011-MM", "Surecom EP-4011-MM", MODEL_EP_4011_MM), BOARD_CAS("EP-4012-MM", "Surecom EP-4012-MM", MODEL_EP_4012_MM), /* TrendNET products */ BOARD_NFS("TN-U100", "TrendNET TN-U100", MODEL_TN_U100), BOARD_NFS("TN-U200", "TrendNET TN-U200", MODEL_TN_U200), {.model = NULL}};/* * 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)#define WARN(fmt, ...) do { \ fprintf(stderr, "[%s] *** warning: " fmt "\n", \ progname, ## __VA_ARGS__ ); \} while (0)#define DBG(lev, fmt, ...) do { \ if (verblevel < lev) \ break;\ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \} while (0)#define ERR_FATAL -1#define ERR_INVALID_IMAGE -2voidusage(int status){ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; struct board_info *board; fprintf(stream, "Usage: %s [OPTIONS...] <file>\n", progname); fprintf(stream,"\n""Options:\n"" -B <board> create image for the board specified with <board>.\n"" valid <board> values:\n" ); for (board = boards; board->model != NULL; board++){ fprintf(stream," %-12s: %s\n", board->model, board->name); }; fprintf(stream," -d don't throw error on invalid images\n"" -k keep invalid images\n"" -K <file> add kernel to the image\n"" -C <file> add custom filesystem to the image\n"" -h show this screen\n""Parameters:\n"" <file> write output to the file <file>\n" ); exit(status);}static inline uint32_t align(uint32_t base, uint32_t alignment){ uint32_t ret; if (alignment) { ret = (base + alignment - 1); ret &= ~(alignment-1); } else { ret = base; } return ret;}/* * argument parsing */intstr2u32(char *arg, uint32_t *val){ char *err = NULL; uint32_t t; errno=0; t = strtoul(arg, &err, 0); if (errno || (err==arg) || ((err != NULL) && *err)) { return -1; } *val = t; return 0;}intstr2u16(char *arg, uint16_t *val){ char *err = NULL; uint32_t t; errno=0; t = strtoul(arg, &err, 0); if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) { return -1; } *val = t & 0xFFFF; return 0;}intstr2u8(char *arg, uint8_t *val){ char *err = NULL; uint32_t t; errno=0; t = strtoul(arg, &err, 0); if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { return -1; } *val = t & 0xFF; return 0;}intparse_arg(char *arg, char *buf, char *argv[]){ int res = 0; size_t argl; char *tok; char **ap = &buf; int i; memset(argv, 0, MAX_ARG_COUNT * sizeof(void *)); if ((arg == NULL)) { /* no arguments */ return 0; } argl = strlen(arg); if (argl == 0) { /* no arguments */ return 0; } if (argl >= MAX_ARG_LEN) { /* argument is too long */ argl = MAX_ARG_LEN-1; } memcpy(buf, arg, argl); buf[argl] = '\0'; for (i = 0; i < MAX_ARG_COUNT; i++) { tok = strsep(ap, ":"); if (tok == NULL) { break; }#if 0 else if (tok[0] == '\0') { break; }#endif argv[i] = tok; res++; } return res;}intrequired_arg(char c, char *arg){ if (arg == NULL || *arg != '-') return 0; ERR("option -%c requires an argument\n", c); return ERR_FATAL;}intis_empty_arg(char *arg){ int ret = 1; if (arg != NULL) { if (*arg) ret = 0; }; return ret;}voidcsum8_update(uint8_t *p, uint32_t len, struct csum_state *css){ for ( ; len > 0; len --) { css->val += *p++; }}uint16_tcsum8_get(struct csum_state *css){ uint8_t t; t = css->val; return ~t + 1;}voidcsum16_update(uint8_t *p, uint32_t len, struct csum_state *css){ uint16_t t; if (css->odd) { t = css->tmp + (p[0]<<8); css->val += LE16_TO_HOST(t); css->odd = 0; len--; p++; } for ( ; len > 1; len -= 2, p +=2 ) { t = p[0] + (p[1] << 8); css->val += LE16_TO_HOST(t); } if (len == 1) { css->tmp = p[0]; css->odd = 1; }}uint16_tcsum16_get(struct csum_state *css){ char pad = 0; csum16_update(&pad, 1, css); return ~css->val + 1;}voidcsum32_update(uint8_t *p, uint32_t len, struct csum_state *css){ uint32_t t; for ( ; len > 3; len -= 4, p += 4 ) { t = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); css->val ^= t; }}uint32_tcsum32_get(struct csum_state *css){ return css->val;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -