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 
usage(void)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 
main(int argc,char ** argv)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 }
157