| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | $Id: fore200e_mkfirm.c,v 1.1 2000/02/21 16:04:32 davem Exp $ | 
|  | 3 |  | 
|  | 4 | mkfirm.c: generates a C readable file from a binary firmware image | 
|  | 5 |  | 
|  | 6 | Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999. | 
|  | 7 |  | 
|  | 8 | This software may be used and distributed according to the terms | 
|  | 9 | of the GNU General Public License, incorporated herein by reference. | 
|  | 10 | */ | 
|  | 11 |  | 
|  | 12 | #include <stdio.h> | 
|  | 13 | #include <stdlib.h> | 
|  | 14 | #include <sys/types.h> | 
|  | 15 | #include <time.h> | 
|  | 16 |  | 
|  | 17 | char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */ | 
|  | 18 | char* default_infname  = "<stdin>"; | 
|  | 19 | char* default_outfname = "<stdout>"; | 
|  | 20 |  | 
|  | 21 | char* progname; | 
|  | 22 | int   verbose  = 0; | 
|  | 23 | int   inkernel = 0; | 
|  | 24 |  | 
|  | 25 |  | 
|  | 26 | void usage(void) | 
|  | 27 | { | 
|  | 28 | fprintf(stderr, | 
|  | 29 | "%s: [-v] [-k] [-b basename ] [-i firmware.bin] [-o firmware.c]\n", | 
|  | 30 | progname); | 
|  | 31 | exit(-1); | 
|  | 32 | } | 
|  | 33 |  | 
|  | 34 |  | 
|  | 35 | int main(int argc, char** argv) | 
|  | 36 | { | 
|  | 37 | time_t   now; | 
|  | 38 | char*    infname  = NULL; | 
|  | 39 | char*    outfname = NULL; | 
|  | 40 | char*    basename = NULL; | 
|  | 41 | FILE*    infile; | 
|  | 42 | FILE*    outfile; | 
|  | 43 | unsigned firmsize; | 
|  | 44 | int      c; | 
|  | 45 |  | 
|  | 46 | progname = *(argv++); | 
|  | 47 |  | 
|  | 48 | while (argc > 1) { | 
|  | 49 | if ((*argv)[0] == '-') { | 
|  | 50 | switch ((*argv)[1]) { | 
|  | 51 | case 'i': | 
|  | 52 | if (argc-- < 3) | 
|  | 53 | usage(); | 
|  | 54 | infname = *(++argv); | 
|  | 55 | break; | 
|  | 56 | case 'o': | 
|  | 57 | if (argc-- < 3) | 
|  | 58 | usage(); | 
|  | 59 | outfname = *(++argv); | 
|  | 60 | break; | 
|  | 61 | case 'b': | 
|  | 62 | if (argc-- < 3) | 
|  | 63 | usage(); | 
|  | 64 | basename = *(++argv); | 
|  | 65 | break; | 
|  | 66 | case 'v': | 
|  | 67 | verbose = 1; | 
|  | 68 | break; | 
|  | 69 | case 'k': | 
|  | 70 | inkernel = 1; | 
|  | 71 | break; | 
|  | 72 | default: | 
|  | 73 | usage(); | 
|  | 74 | } | 
|  | 75 | } | 
|  | 76 | else { | 
|  | 77 | usage(); | 
|  | 78 | } | 
|  | 79 | argc--; | 
|  | 80 | argv++; | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | if (infname != NULL) { | 
|  | 84 | infile = fopen(infname, "r"); | 
|  | 85 | if (infile == NULL) { | 
|  | 86 | fprintf(stderr, "%s: can't open %s for reading\n", | 
|  | 87 | progname, infname); | 
|  | 88 | exit(-2); | 
|  | 89 | } | 
|  | 90 | } | 
|  | 91 | else { | 
|  | 92 | infile = stdin; | 
|  | 93 | infname = default_infname; | 
|  | 94 | } | 
|  | 95 |  | 
|  | 96 | if (outfname) { | 
|  | 97 | outfile = fopen(outfname, "w"); | 
|  | 98 | if (outfile == NULL) { | 
|  | 99 | fprintf(stderr, "%s: can't open %s for writing\n", | 
|  | 100 | progname, outfname); | 
|  | 101 | exit(-3); | 
|  | 102 | } | 
|  | 103 | } | 
|  | 104 | else { | 
|  | 105 | outfile = stdout; | 
|  | 106 | outfname = default_outfname; | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | if (basename == NULL) | 
|  | 110 | basename = default_basename; | 
|  | 111 |  | 
|  | 112 | if (verbose) { | 
|  | 113 | fprintf(stderr, "%s: input file = %s\n", progname, infname ); | 
|  | 114 | fprintf(stderr, "%s: output file = %s\n", progname, outfname ); | 
|  | 115 | fprintf(stderr, "%s: firmware basename = %s\n", progname, basename ); | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | time(&now); | 
|  | 119 | fprintf(outfile, "/*\n  generated by %s from %s on %s" | 
|  | 120 | "  DO NOT EDIT!\n*/\n\n", | 
|  | 121 | progname, infname, ctime(&now)); | 
|  | 122 |  | 
|  | 123 | if (inkernel) | 
|  | 124 | fprintf(outfile, "#include <linux/init.h>\n\n" ); | 
|  | 125 |  | 
|  | 126 | /* XXX force 32 bit alignment? */ | 
|  | 127 | fprintf(outfile, "const unsigned char%s %s_data[] = {\n", | 
|  | 128 | inkernel ? " __initdata" : "", basename ); | 
|  | 129 |  | 
|  | 130 | c = getc(infile); | 
|  | 131 | fprintf(outfile,"\t0x%02x", c); | 
|  | 132 | firmsize = 1; | 
|  | 133 |  | 
|  | 134 | while ((c = getc(infile)) >= 0) { | 
|  | 135 |  | 
|  | 136 | if (firmsize++ % 8) | 
|  | 137 | fprintf(outfile,", 0x%02x", c); | 
|  | 138 | else | 
|  | 139 | fprintf(outfile,",\n\t0x%02x", c); | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | fprintf(outfile, "\n};\n\n"); | 
|  | 143 |  | 
|  | 144 | fprintf(outfile, "const unsigned int%s %s_size = %u;\n", | 
|  | 145 | inkernel ? " __initdata" : "", basename, firmsize ); | 
|  | 146 |  | 
|  | 147 | if (infile != stdin) | 
|  | 148 | fclose(infile); | 
|  | 149 | if (outfile != stdout) | 
|  | 150 | fclose(outfile); | 
|  | 151 |  | 
|  | 152 | if(verbose) | 
|  | 153 | fprintf(stderr, "%s: firmware size = %u\n", progname, firmsize); | 
|  | 154 |  | 
|  | 155 | exit(0); | 
|  | 156 | } |