diff options
Diffstat (limited to 'arch/ppc/boot/utils/mkprep.c')
-rw-r--r-- | arch/ppc/boot/utils/mkprep.c | 416 |
1 files changed, 182 insertions, 234 deletions
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c index f6d5a2f2fcf6..192bb397126f 100644 --- a/arch/ppc/boot/utils/mkprep.c +++ b/arch/ppc/boot/utils/mkprep.c | |||
@@ -15,279 +15,227 @@ | |||
15 | * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> | 15 | * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <fcntl.h> | ||
19 | #include <stdio.h> | 18 | #include <stdio.h> |
20 | #include <stdlib.h> | ||
21 | #include <string.h> | 19 | #include <string.h> |
22 | #include <strings.h> | 20 | #include <stdlib.h> |
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | |||
26 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
27 | unsigned long le32_to_cpu(unsigned long x) | ||
28 | { | ||
29 | return (((x & 0x000000ffU) << 24) | | ||
30 | ((x & 0x0000ff00U) << 8) | | ||
31 | ((x & 0x00ff0000U) >> 8) | | ||
32 | ((x & 0xff000000U) >> 24)); | ||
33 | } | ||
34 | |||
35 | |||
36 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
37 | unsigned short le16_to_cpu(unsigned short x) | ||
38 | { | ||
39 | return (((x & 0x00ff) << 8) | | ||
40 | ((x & 0xff00) >> 8)); | ||
41 | } | ||
42 | |||
43 | #define cpu_to_be32(x) (x) | ||
44 | #define be32_to_cpu(x) (x) | ||
45 | #define cpu_to_be16(x) (x) | ||
46 | #define be16_to_cpu(x) (x) | ||
47 | 21 | ||
48 | /* size of read buffer */ | 22 | /* size of read buffer */ |
49 | #define SIZE 0x1000 | 23 | #define SIZE 0x1000 |
50 | 24 | ||
51 | |||
52 | typedef unsigned long dword_t; | ||
53 | typedef unsigned short word_t; | ||
54 | typedef unsigned char byte_t; | ||
55 | typedef byte_t block_t[512]; | ||
56 | typedef byte_t page_t[4096]; | ||
57 | |||
58 | |||
59 | /* | 25 | /* |
60 | * Partition table entry | 26 | * Partition table entry |
61 | * - from the PReP spec | 27 | * - from the PReP spec |
62 | */ | 28 | */ |
63 | typedef struct partition_entry { | 29 | typedef struct partition_entry { |
64 | byte_t boot_indicator; | 30 | unsigned char boot_indicator; |
65 | byte_t starting_head; | 31 | unsigned char starting_head; |
66 | byte_t starting_sector; | 32 | unsigned char starting_sector; |
67 | byte_t starting_cylinder; | 33 | unsigned char starting_cylinder; |
68 | 34 | ||
69 | byte_t system_indicator; | 35 | unsigned char system_indicator; |
70 | byte_t ending_head; | 36 | unsigned char ending_head; |
71 | byte_t ending_sector; | 37 | unsigned char ending_sector; |
72 | byte_t ending_cylinder; | 38 | unsigned char ending_cylinder; |
73 | 39 | ||
74 | dword_t beginning_sector; | 40 | unsigned char beginning_sector[4]; |
75 | dword_t number_of_sectors; | 41 | unsigned char number_of_sectors[4]; |
76 | } partition_entry_t; | 42 | } partition_entry_t; |
77 | 43 | ||
78 | #define BootActive 0x80 | 44 | #define BootActive 0x80 |
79 | #define SystemPrep 0x41 | 45 | #define SystemPrep 0x41 |
80 | 46 | ||
81 | void copy_image(int , int); | 47 | void copy_image(FILE *, FILE *); |
82 | void write_prep_partition(int , int ); | 48 | void write_prep_partition(FILE *, FILE *); |
83 | void write_asm_data( int in, int out ); | 49 | void write_asm_data(FILE *, FILE *); |
84 | 50 | ||
85 | unsigned int elfhdr_size = 65536; | 51 | unsigned int elfhdr_size = 65536; |
86 | 52 | ||
87 | int main(int argc, char *argv[]) | 53 | int main(int argc, char *argv[]) |
88 | { | 54 | { |
89 | int in_fd, out_fd; | 55 | FILE *in, *out; |
90 | int argptr = 1; | 56 | int argptr = 1; |
91 | unsigned int prep = 0; | 57 | int prep = 0; |
92 | unsigned int asmoutput = 0; | 58 | int asmoutput = 0; |
93 | 59 | ||
94 | if ( (argc < 3) || (argc > 4) ) | 60 | if (argc < 3 || argc > 4) { |
95 | { | 61 | fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n", |
96 | fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]); | 62 | argv[0]); |
97 | exit(-1); | 63 | exit(-1); |
98 | } | 64 | } |
99 | 65 | ||
100 | /* needs to handle args more elegantly -- but this is a small/simple program */ | 66 | /* needs to handle args more elegantly -- but this is a small/simple program */ |
101 | 67 | ||
102 | /* check for -pbp */ | 68 | /* check for -pbp */ |
103 | if ( !strcmp( argv[argptr], "-pbp" ) ) | 69 | if (!strcmp(argv[argptr], "-pbp")) { |
104 | { | 70 | prep = 1; |
105 | prep = 1; | 71 | argptr++; |
106 | argptr++; | 72 | } |
107 | } | 73 | |
108 | 74 | /* check for -asm */ | |
109 | /* check for -asm */ | 75 | if (!strcmp(argv[argptr], "-asm")) { |
110 | if ( !strcmp( argv[argptr], "-asm" ) ) | 76 | asmoutput = 1; |
111 | { | 77 | argptr++; |
112 | asmoutput = 1; | 78 | } |
113 | argptr++; | 79 | |
114 | } | 80 | /* input file */ |
115 | 81 | if (!strcmp(argv[argptr], "-")) | |
116 | /* input file */ | 82 | in = stdin; |
117 | if ( !strcmp( argv[argptr], "-" ) ) | 83 | else if (!(in = fopen(argv[argptr], "r"))) |
118 | in_fd = 0; /* stdin */ | 84 | exit(-1); |
119 | else | 85 | argptr++; |
120 | if ((in_fd = open( argv[argptr] , 0)) < 0) | 86 | |
121 | exit(-1); | 87 | /* output file */ |
122 | argptr++; | 88 | if (!strcmp(argv[argptr], "-")) |
123 | 89 | out = stdout; | |
124 | /* output file */ | 90 | else if (!(out = fopen(argv[argptr], "w"))) |
125 | if ( !strcmp( argv[argptr], "-" ) ) | 91 | exit(-1); |
126 | out_fd = 1; /* stdout */ | 92 | argptr++; |
127 | else | 93 | |
128 | if ((out_fd = creat( argv[argptr] , 0755)) < 0) | 94 | /* skip elf header in input file */ |
129 | exit(-1); | 95 | /*if ( !prep )*/ |
130 | argptr++; | 96 | fseek(in, elfhdr_size, SEEK_SET); |
131 | 97 | ||
132 | /* skip elf header in input file */ | 98 | /* write prep partition if necessary */ |
133 | /*if ( !prep )*/ | 99 | if (prep) |
134 | lseek(in_fd, elfhdr_size, SEEK_SET); | 100 | write_prep_partition(in, out); |
135 | 101 | ||
136 | /* write prep partition if necessary */ | 102 | /* write input image to bootimage */ |
137 | if ( prep ) | 103 | if (asmoutput) |
138 | write_prep_partition( in_fd, out_fd ); | 104 | write_asm_data(in, out); |
139 | 105 | else | |
140 | /* write input image to bootimage */ | 106 | copy_image(in, out); |
141 | if ( asmoutput ) | 107 | |
142 | write_asm_data( in_fd, out_fd ); | 108 | return 0; |
143 | else | ||
144 | copy_image(in_fd, out_fd); | ||
145 | |||
146 | return 0; | ||
147 | } | 109 | } |
148 | 110 | ||
149 | void write_prep_partition(int in, int out) | 111 | void store_le32(unsigned int v, unsigned char *p) |
150 | { | 112 | { |
151 | unsigned char block[512]; | 113 | p[0] = v; |
152 | partition_entry_t pe; | 114 | p[1] = v >>= 8; |
153 | dword_t *entry = (dword_t *)&block[0]; | 115 | p[2] = v >>= 8; |
154 | dword_t *length = (dword_t *)&block[sizeof(long)]; | 116 | p[3] = v >> 8; |
155 | struct stat info; | 117 | } |
156 | 118 | ||
157 | if (fstat(in, &info) < 0) | 119 | void write_prep_partition(FILE *in, FILE *out) |
158 | { | 120 | { |
159 | fprintf(stderr,"info failed\n"); | 121 | unsigned char block[512]; |
160 | exit(-1); | 122 | partition_entry_t pe; |
161 | } | 123 | unsigned char *entry = block; |
162 | 124 | unsigned char *length = block + 4; | |
163 | bzero( block, sizeof block ); | 125 | long pos = ftell(in), size; |
164 | 126 | ||
165 | /* set entry point and boot image size skipping over elf header */ | 127 | if (fseek(in, 0, SEEK_END) < 0) { |
166 | #ifdef __i386__ | 128 | fprintf(stderr,"info failed\n"); |
167 | *entry = 0x400/*+65536*/; | 129 | exit(-1); |
168 | *length = info.st_size-elfhdr_size+0x400; | 130 | } |
169 | #else | 131 | size = ftell(in); |
170 | *entry = cpu_to_le32(0x400/*+65536*/); | 132 | if (fseek(in, pos, SEEK_SET) < 0) { |
171 | *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); | 133 | fprintf(stderr,"info failed\n"); |
172 | #endif /* __i386__ */ | 134 | exit(-1); |
173 | 135 | } | |
174 | /* sets magic number for msdos partition (used by linux) */ | 136 | |
175 | block[510] = 0x55; | 137 | memset(block, '\0', sizeof(block)); |
176 | block[511] = 0xAA; | 138 | |
177 | 139 | /* set entry point and boot image size skipping over elf header */ | |
178 | /* | 140 | store_le32(0x400/*+65536*/, entry); |
179 | * Build a "PReP" partition table entry in the boot record | 141 | store_le32(size-elfhdr_size+0x400, length); |
180 | * - "PReP" may only look at the system_indicator | 142 | |
181 | */ | 143 | /* sets magic number for msdos partition (used by linux) */ |
182 | pe.boot_indicator = BootActive; | 144 | block[510] = 0x55; |
183 | pe.system_indicator = SystemPrep; | 145 | block[511] = 0xAA; |
184 | /* | 146 | |
185 | * The first block of the diskette is used by this "boot record" which | 147 | /* |
186 | * actually contains the partition table. (The first block of the | 148 | * Build a "PReP" partition table entry in the boot record |
187 | * partition contains the boot image, but I digress...) We'll set up | 149 | * - "PReP" may only look at the system_indicator |
188 | * one partition on the diskette and it shall contain the rest of the | 150 | */ |
189 | * diskette. | 151 | pe.boot_indicator = BootActive; |
190 | */ | 152 | pe.system_indicator = SystemPrep; |
191 | pe.starting_head = 0; /* zero-based */ | 153 | /* |
192 | pe.starting_sector = 2; /* one-based */ | 154 | * The first block of the diskette is used by this "boot record" which |
193 | pe.starting_cylinder = 0; /* zero-based */ | 155 | * actually contains the partition table. (The first block of the |
194 | pe.ending_head = 1; /* assumes two heads */ | 156 | * partition contains the boot image, but I digress...) We'll set up |
195 | pe.ending_sector = 18; /* assumes 18 sectors/track */ | 157 | * one partition on the diskette and it shall contain the rest of the |
196 | pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ | 158 | * diskette. |
197 | 159 | */ | |
198 | /* | 160 | pe.starting_head = 0; /* zero-based */ |
199 | * The "PReP" software ignores the above fields and just looks at | 161 | pe.starting_sector = 2; /* one-based */ |
200 | * the next two. | 162 | pe.starting_cylinder = 0; /* zero-based */ |
201 | * - size of the diskette is (assumed to be) | 163 | pe.ending_head = 1; /* assumes two heads */ |
202 | * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) | 164 | pe.ending_sector = 18; /* assumes 18 sectors/track */ |
203 | * - unlike the above sector numbers, the beginning sector is zero-based! | 165 | pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ |
204 | */ | 166 | |
167 | /* | ||
168 | * The "PReP" software ignores the above fields and just looks at | ||
169 | * the next two. | ||
170 | * - size of the diskette is (assumed to be) | ||
171 | * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) | ||
172 | * - unlike the above sector numbers, the beginning sector is zero-based! | ||
173 | */ | ||
205 | #if 0 | 174 | #if 0 |
206 | pe.beginning_sector = cpu_to_le32(1); | 175 | store_le32(1, pe.beginning_sector); |
207 | #else | ||
208 | /* This has to be 0 on the PowerStack? */ | ||
209 | #ifdef __i386__ | ||
210 | pe.beginning_sector = 0; | ||
211 | #else | 176 | #else |
212 | pe.beginning_sector = cpu_to_le32(0); | 177 | /* This has to be 0 on the PowerStack? */ |
213 | #endif /* __i386__ */ | 178 | store_le32(0, pe.beginning_sector); |
214 | #endif | 179 | #endif |
215 | 180 | ||
216 | #ifdef __i386__ | 181 | store_le32(2*18*80-1, pe.number_of_sectors); |
217 | pe.number_of_sectors = 2*18*80-1; | ||
218 | #else | ||
219 | pe.number_of_sectors = cpu_to_le32(2*18*80-1); | ||
220 | #endif /* __i386__ */ | ||
221 | 182 | ||
222 | memcpy(&block[0x1BE], &pe, sizeof(pe)); | 183 | memcpy(&block[0x1BE], &pe, sizeof(pe)); |
223 | 184 | ||
224 | write( out, block, sizeof(block) ); | 185 | fwrite(block, sizeof(block), 1, out); |
225 | write( out, entry, sizeof(*entry) ); | 186 | fwrite(entry, 4, 1, out); |
226 | write( out, length, sizeof(*length) ); | 187 | fwrite(length, 4, 1, out); |
227 | /* set file position to 2nd sector where image will be written */ | 188 | /* set file position to 2nd sector where image will be written */ |
228 | lseek( out, 0x400, SEEK_SET ); | 189 | fseek( out, 0x400, SEEK_SET ); |
229 | } | 190 | } |
230 | 191 | ||
231 | 192 | ||
232 | 193 | ||
233 | void | 194 | void copy_image(FILE *in, FILE *out) |
234 | copy_image(int in, int out) | ||
235 | { | 195 | { |
236 | char buf[SIZE]; | 196 | char buf[SIZE]; |
237 | int n; | 197 | int n; |
238 | 198 | ||
239 | while ( (n = read(in, buf, SIZE)) > 0 ) | 199 | while ( (n = fread(buf, 1, SIZE, in)) > 0 ) |
240 | write(out, buf, n); | 200 | fwrite(buf, 1, n, out); |
241 | } | 201 | } |
242 | 202 | ||
243 | 203 | ||
244 | void | 204 | void |
245 | write_asm_data( int in, int out ) | 205 | write_asm_data(FILE *in, FILE *out) |
246 | { | 206 | { |
247 | int i, cnt, pos, len; | 207 | int i, cnt, pos = 0; |
248 | unsigned int cksum, val; | 208 | unsigned int cksum = 0, val; |
249 | unsigned char *lp; | 209 | unsigned char *lp; |
250 | unsigned char buf[SIZE]; | 210 | unsigned char buf[SIZE]; |
251 | unsigned char str[256]; | 211 | size_t len; |
252 | 212 | ||
253 | write( out, "\t.data\n\t.globl input_data\ninput_data:\n", | 213 | fputs("\t.data\n\t.globl input_data\ninput_data:\n", out); |
254 | strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); | 214 | while ((len = fread(buf, 1, sizeof(buf), in)) > 0) { |
255 | pos = 0; | 215 | cnt = 0; |
256 | cksum = 0; | 216 | lp = buf; |
257 | while ((len = read(in, buf, sizeof(buf))) > 0) | 217 | /* Round up to longwords */ |
258 | { | 218 | while (len & 3) |
259 | cnt = 0; | 219 | buf[len++] = '\0'; |
260 | lp = (unsigned char *)buf; | 220 | for (i = 0; i < len; i += 4) { |
261 | len = (len + 3) & ~3; /* Round up to longwords */ | 221 | if (cnt == 0) |
262 | for (i = 0; i < len; i += 4) | 222 | fputs("\t.long\t", out); |
263 | { | 223 | fprintf(out, "0x%02X%02X%02X%02X", |
264 | if (cnt == 0) | 224 | lp[0], lp[1], lp[2], lp[3]); |
265 | { | 225 | val = *(unsigned long *)lp; |
266 | write( out, "\t.long\t", strlen( "\t.long\t" ) ); | 226 | cksum ^= val; |
267 | } | 227 | lp += 4; |
268 | sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); | 228 | if (++cnt == 4) { |
269 | write( out, str, strlen(str) ); | 229 | cnt = 0; |
270 | val = *(unsigned long *)lp; | 230 | fprintf(out, " # %x \n", pos+i-12); |
271 | cksum ^= val; | 231 | } else { |
272 | lp += 4; | 232 | fputs(",", out); |
273 | if (++cnt == 4) | 233 | } |
274 | { | 234 | } |
275 | cnt = 0; | 235 | if (cnt) |
276 | sprintf( str, " # %x \n", pos+i-12); | 236 | fputs("0\n", out); |
277 | write( out, str, strlen(str) ); | 237 | pos += len; |
278 | } else | 238 | } |
279 | { | 239 | fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); |
280 | write( out, ",", 1 ); | 240 | fprintf(stderr, "cksum = %x\n", cksum); |
281 | } | ||
282 | } | ||
283 | if (cnt) | ||
284 | { | ||
285 | write( out, "0\n", 2 ); | ||
286 | } | ||
287 | pos += len; | ||
288 | } | ||
289 | sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); | ||
290 | write( out, str, strlen(str) ); | ||
291 | |||
292 | fprintf(stderr, "cksum = %x\n", cksum); | ||
293 | } | 241 | } |