1 /*
2 *
3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
38 /* Combine two boot tables.
39 * usage bfmerge file1 file2 [file3 [file4 [...]]]
40 * The output is to stdout
41 *
42 * */
44 #include <stdio.h>
45 #include <malloc.h>
47 int asciiByte (unsigned char c)
48 {
49 if ((c >= '0') && (c <= '9'))
50 return (1);
52 if ((c >= 'A') && (c <= 'F'))
53 return (1);
55 return (0);
56 }
58 int toNum (unsigned char c)
59 {
60 if ((c >= '0') && (c <= '9'))
61 return (c - '0');
63 return (c - 'A' + 10);
65 }
68 /* Copy a line from s to stdout */
69 void lineCpy (FILE *s)
70 {
71 char iline[132];
73 fgets (iline, 131, s);
74 fputs (iline, stdout);
76 }
78 /* Toss a line */
79 void lineToss (FILE *s)
80 {
81 char iline[132];
83 fgets (iline, 131, s);
85 }
87 /* Read a .b file. */
88 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
89 {
90 unsigned char x, y;
91 int byteCount = 0;
93 for (;;) {
95 /* read the 1st ascii char */
96 do {
97 x = fgetc (s);
98 if (x == (unsigned char)EOF)
99 return (byteCount);
101 } while (!asciiByte(x));
103 /* Read the next ascii char */
104 y = fgetc (s);
105 if (y == (unsigned char)EOF)
106 return (byteCount);
107 if (asciiByte(y))
108 data[byteCount++] = (toNum(x) << 4) | toNum (y);
110 if (byteCount >= maxSize) {
111 fprintf (stderr, "Max input array size exceeded\n");
112 return (-1);
113 }
115 }
117 }
119 unsigned dwordConvert (unsigned char *data)
120 {
121 unsigned value;
122 unsigned char c[4];
123 int i;
125 c[0] = c[1] = c[2] = c[3] = 0;
127 for (i = 0; i < 4; i++) {
128 c[i] = data[i];
129 }
131 value = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
133 return (value);
135 }
138 int bparse (unsigned char *dataSet, int l)
139 {
140 unsigned int secsize;
142 do {
144 secsize = dwordConvert (&dataSet[l]);
145 secsize = (secsize + 3) & 0xfffffffc; /* segment pad */
146 l = l + secsize + 8; /* 4 bytes length, 4 bytes address */
148 } while (secsize);
150 /* Back up to the zero section size */
151 l = l - 8;
153 return (l);
155 }
158 #define SIZE 1000000
159 #define APPEND 100000
161 int main (int argc, char *argv[])
162 {
163 FILE *strin;
164 unsigned char *dataSet;
165 unsigned char *appSet;
166 unsigned int addr;
167 unsigned int secsize;
168 int asize;
169 int i, j;
170 int nbytes;
171 int p;
173 /* Must have at least two input files */
174 if (argc < 3) {
175 fprintf (stderr, "usage: %s file1 file2 [file3 [file4 [...]]]\n", argv[0]);
176 return (-1);
177 }
179 /* Allocate memory for the data set */
180 dataSet = malloc (SIZE * sizeof (unsigned char));
181 if (dataSet == NULL) {
182 fprintf (stderr, "%s: malloc failure\n", argv[0]);
183 return (-1);
184 }
186 appSet = malloc (APPEND * sizeof (unsigned char ));
187 if (appSet == NULL) {
188 fprintf (stderr, "%s malloc failure\n", argv[0]);
189 return (-1);
190 }
193 /* The first data file is handled seperately */
194 strin = fopen (argv[1], "r");
195 if (strin == NULL) {
196 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[1]);
197 free (dataSet);
198 return (-1);
199 }
201 /* Copy the first two lines of the input file to stdout */
202 lineCpy (strin);
203 lineCpy (strin);
205 /* Read in the first data set */
206 asize = readBFile (strin, dataSet, SIZE);
207 fclose (strin);
209 /* Parse the file, skipping the entry symbol */
210 p = 4;
211 p = bparse (dataSet, p);
214 /* Add the remaining data sets */
216 for (i = 2; i < argc; i++) {
218 strin = fopen (argv[i], "r");
219 if (strin == NULL) {
220 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[i]);
221 free (dataSet);
222 return (-1);
223 }
225 /* Toss the first two lines */
226 lineToss (strin);
227 lineToss (strin);
229 asize = readBFile (strin, appSet, APPEND);
230 fclose (strin);
232 /* Append the new data set, skip the 4 bytes of entry symbol */
233 for (j = 0; j < asize-4; j++)
234 dataSet[p+j] = appSet[j+4];
236 /* reparse from the current point */
237 p = bparse (dataSet, p);
239 }
241 /* Add the 0 section size */
242 for (i = 0; i < 4; i++)
243 dataSet[p++] = 0;
246 /* Write out the data */
247 for (i = 0; i < p; i++) {
248 fprintf (stdout, "%02X", dataSet[i]);
250 if ( ((i+1) % 24) )
251 fprintf (stdout, " ");
252 else
253 fprintf (stdout, "\n");
255 }
257 /* Write the trailing character */
258 fprintf (stdout, "\n%c",3);
260 free (dataSet);
262 return (0);
264 }