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 /* Append a boot table section to the end of a boot table
39 * usage: bfaddsect infile addr byte1 [bytes2 [byte3 [...]]]
40 * The output is to stdout
41 *
42 * All values are taken to be btye values */
45 #include <stdio.h>
46 #include <malloc.h>
50 int asciiByte (unsigned char c)
51 {
52 if ((c >= '0') && (c <= '9'))
53 return (1);
55 if ((c >= 'A') && (c <= 'F'))
56 return (1);
58 return (0);
59 }
61 int toNum (unsigned char c)
62 {
63 if ((c >= '0') && (c <= '9'))
64 return (c - '0');
66 return (c - 'A' + 10);
68 }
71 /* Copy a line from s to stdout */
72 void lineCpy (FILE *s)
73 {
74 char iline[132];
76 fgets (iline, 131, s);
77 fputs (iline, stdout);
79 }
81 /* Read a .b file. */
82 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
83 {
84 unsigned char x, y;
85 int byteCount = 0;
87 for (;;) {
89 /* read the 1st ascii char */
90 do {
91 x = fgetc (s);
92 if (x == (unsigned char)EOF)
93 return (byteCount);
95 } while (!asciiByte(x));
97 /* Read the next ascii char */
98 y = fgetc (s);
99 if (y == (unsigned char)EOF)
100 return (byteCount);
101 if (asciiByte(y))
102 data[byteCount++] = (toNum(x) << 4) | toNum (y);
104 if (byteCount >= maxSize) {
105 fprintf (stderr, "Max input array size exceeded\n");
106 return (-1);
107 }
109 }
111 }
113 unsigned dwordConvert (unsigned char *data)
114 {
115 unsigned value;
116 unsigned char c[4];
117 int i;
119 c[0] = c[1] = c[2] = c[3] = 0;
121 for (i = 0; i < 4; i++) {
122 c[i] = data[i];
123 }
125 value = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
127 return (value);
129 }
131 #define SIZE 0x100000 /* max number of bytes in the array */
132 #define MAX_BYTES 64 /* max size of the boot table */
134 int main (int argc, char *argv[])
135 {
136 FILE *strin;
137 unsigned char *dataSet;
138 unsigned int addr;
139 unsigned int secsize;
140 unsigned char newchars[MAX_BYTES];
141 int i;
142 int nbytes;
143 int asize;
144 int p;
147 /* get the args */
148 if (argc < 4) {
149 fprintf (stderr, "usage: %s infile hex_addr byte1 [byte2 [byte3 [ ...byte64]]]\n", argv[0]);
150 return (-1);
151 }
153 /* input file */
154 strin = fopen (argv[1], "r");
155 if (strin == NULL) {
156 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[1]);
157 return (-1);
158 }
160 /* Address */
161 sscanf (argv[2], "%x", &addr);
163 /* Number of bytes */
164 nbytes = argc - 3;
165 for (i = 0; i < nbytes; i++)
166 sscanf (argv[i+3], "%x", &newchars[i]);
169 /* Allocate memory for the data set */
170 dataSet = malloc (SIZE * sizeof (unsigned char));
171 if (dataSet == NULL) {
172 fprintf (stderr, "%s: malloc failure\n", argv[0]);
173 return (-1);
174 }
176 /* Copy the first two lines of the input file to stdout */
177 lineCpy (strin);
178 lineCpy (strin);
180 /* Read the data into the byte stream */
181 asize = readBFile (strin, dataSet, SIZE);
182 fclose (strin);
184 /* Parse the input file. Prepend the new section at the end */
186 /* Just skip the entry address */
187 p = 4;
189 do {
190 secsize = dwordConvert (&dataSet[p]);
191 secsize = (secsize + 3) & 0xfffffffc; /* segment pad */
192 p = p + secsize + 8; /* 4 bytes length, 4 bytes address */
193 } while (secsize);
195 /* back up to the zero section size */
196 p = p - 8;
198 /* p now points to the 0 length entry. Put the new data here */
199 /* The section size */
200 dataSet[p++] = (nbytes >> 24) & 0xff;
201 dataSet[p++] = (nbytes >> 16) & 0xff;
202 dataSet[p++] = (nbytes >> 8) & 0xff;
203 dataSet[p++] = (nbytes >> 0) & 0xff;
205 /* Put the section address */
206 dataSet[p++] = (addr >> 24) & 0xff;
207 dataSet[p++] = (addr >> 16) & 0xff;
208 dataSet[p++] = (addr >> 8) & 0xff;
209 dataSet[p++] = (addr >> 0) & 0xff;
211 /* Put the data */
212 for (i = 0; i < nbytes; i++)
213 dataSet[p++] = newchars[i];
215 while (p % 4)
216 dataSet[p++] = 0;
218 /* Add the 0 length section */
219 for (i = 0; i < 4; i++)
220 dataSet[p++] = 0;
223 /* Write out the data */
224 for (i = 0; i < p; i++) {
225 fprintf (stdout, "%02X", dataSet[i]);
227 if ( ((i+1) % 24) )
228 fprintf (stdout, " ");
229 else
230 fprintf (stdout, "\n");
232 }
234 /* Write the trailing character */
235 fprintf (stdout, "\n%c",3);
237 free (dataSet);
239 return (0);
241 }