?? packimage.c
字號:
/* * Copyright (C) 2007 Jiong Zhao <jiong.zhao@mail.tongji.edu.cn> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* December 12 2007 * * This program is used to create a binary file for Xscale IXP425 * development board produced by FUDANTECH co. The binary file is * a packed one composed by multi images to be written into FLASH. * * To be ease of use, we refer to available similar programs to make * the usage as same as possible. Mostly we refernced the program * programmed by Manuel Novoa III <mjn3@codepoet.org>. But this * program is totaly different from that one. * */#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <stdint.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <byteswap.h>/* Define the machine's endian type. If we operate on Big Endian data, * then we use READ32_BE(X) and STORE32_BE(X). If we operate on Little * Endian data, then we should use READ32_LE(X) and STORE32_BE(X). */#define __BYTE_ORDER __LITTLE_ENDIAN // Host machine - i386 type.//#define __BYTE_ORDER __BIG_ENDIAN // Target machine - ARM type.#if __BYTE_ORDER == __BIG_ENDIAN // Program used on ARM type.#define STORE32_LE(X) bswap_32(X)#define READ32_LE(X) bswap_32(X)#define STORE32_BE(X) (X)#define READ32_BE(X) (X)#elif __BYTE_ORDER == __LITTLE_ENDIAN // Program used on i386 type.#define STORE32_LE(X) (X)#define READ32_LE(X) (X)#define STORE32_BE(X) bswap_32(X)#define READ32_BE(X) bswap_32(X)#else#error unkown endianness!#endifuint32_t crc32buf(char *buf, size_t len);/**********************************************************************/#define PAK_MAGIC 0x41435358 /* "XSCA" */#define PAK_VERSION 1#define PAK_MAX_LEN 0xB00000#define MAX_NAME_LEN 15#define MAX_PAK_IMAGES 5struct img_header { uint32_t offset; /* image begin offset in this pack file. -1 end.*/ uint32_t len; /* length of pure file. */ uint32_t mtdofs; /* null if this is the last. */ uint32_t mtdno; /* in /proc/mtd: dev */ char mtdname[MAX_NAME_LEN+1]; /* in /proc/mtd: name */ char filename[MAX_NAME_LEN+1]; /* filename when packed (w/o path) */} img_header_t ; struct pak_header { uint32_t magic; /* "XSCA" */ uint32_t len; /* Length of file including header */ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ uint32_t icount; /* Total image file number. */ struct img_header img[MAX_PAK_IMAGES]; };/**********************************************************************//* The header occupis 256 bytes. The first image file is stored beginning *//* from this location. Only 5 image files can be stored together. */void usage(void) __attribute__ (( __noreturn__ ));void usage(void){ fprintf(stderr, "Usage: packimage [-o outfile] [-m maxlen] [-b offset] [-d mtdno] [-n mtdname] [-f file] [-f file [-f file]]\n"); exit(EXIT_FAILURE);}int main(int argc, char **argv){ FILE *fout = stdout; FILE *fin; char *ofn = NULL; char *buf, *name; char *e; int c, i, append = 0; size_t n; uint32_t cur_len; unsigned long maxlen = PAK_MAX_LEN; struct pak_header *pak; fprintf(stderr, "\nPackimage files for IXP425. - v0.2.1\n"); if (!(buf = malloc(maxlen))) { fprintf(stderr, "Not enough memory to run, malloc failed\n"); return EXIT_FAILURE; } pak = (struct pak_header *) buf; for (n=0; n<MAX_PAK_IMAGES; n++) { pak->img[n].mtdno = -1 ; pak->img[n].len = 0; } /* The magic number is a special case and always in little endian. */ pak->magic = STORE32_LE(PAK_MAGIC); cur_len = sizeof(struct pak_header); // 0x100 first. fin = NULL; i = 0; n = 0 ; // Image No. while ((c = getopt(argc, argv, "-:o:m:b:n:d:f:A:")) != -1) { switch (c) { case 'A': append = 1; /* fall through */ case 'f': case 1 : if (!append) pak->img[i].offset = STORE32_BE(cur_len); if (!(fin = fopen(optarg, "r"))) { fprintf(stderr, "can not open \"%s\" for reading\n", optarg); usage(); } n = fread(buf + cur_len, 1, maxlen - cur_len, fin); if (!feof(fin)) { fprintf(stderr, "fread failure or file \"%s\" too large\n",optarg); fclose(fin); return EXIT_FAILURE; } fclose(fin); errno = 0; name = strrchr(optarg,'/'); name = name ? name + 1: optarg ; fprintf(stderr, "Processing file: %s\n", name); if (name) { strncpy(pak->img[i].filename,name,MAX_NAME_LEN); if (strlen(name) > MAX_NAME_LEN ) fprintf(stderr, "WARNING: Filename %s truncated\n",name); } else { sprintf(pak->img[i].filename, "Imagefile%d", i); } pak->img[i].len = STORE32_BE(n); i++; #undef ROUND#define ROUND 4 if (n & (ROUND-1)) { memset(buf + cur_len + n, 0, ROUND - (n & (ROUND-1))); n += ROUND - (n & (ROUND-1)); } cur_len += n; append = 0; break; case 'o': ofn = optarg; if (ofn && !(fout = fopen(ofn, "w"))) { fprintf(stderr, "can not open \"%s\" for writing\n", ofn); usage(); } break; case 'm': // Max len. errno = 0; maxlen = strtoul(optarg, &e, 0); if (errno || (e == optarg) || *e) { fprintf(stderr, "illegal numeric string\n"); usage(); }#undef ROUND#define ROUND 0x1000 if (maxlen & (ROUND-1)) { maxlen += (ROUND - (maxlen & (ROUND-1))); } if (maxlen < ROUND) { fprintf(stderr, "maxlen too small (or wrapped)\n"); usage(); } if (maxlen > PAK_MAX_LEN) { fprintf(stderr, "WARNING: maxlen exceeds default maximum! Beware of overwriting nvram!\n"); } if (!(buf = realloc(buf,maxlen))) { fprintf(stderr, "realloc failed"); return EXIT_FAILURE; } break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -