makemask.c
2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "boot_image.h"
#define min2(a, b) ( (a)<(b) ? (a) : (b) )
int swapped;
#define CKSUM_START 0x1000
#define CKSUM_LENGTH 0x100000
#define CKSUM_END (CKSUM_START + CKSUM_LENGTH)
#define CKSUM_STARTVAL 0xf8ca4ddc
#define ROL(i, b) (((i)<<(b)) | ((i)>>(32-(b))))
#define L2B(l, b, s) (b)[0^(s)] = ((l)>>24)&0xff; \
(b)[1^(s)] = ((l)>>16)&0xff; \
(b)[2^(s)] = ((l)>> 8)&0xff; \
(b)[3^(s)] = ((l) )&0xff;
#define HEADER_MAGIC 0x80371240
void
calc3(FILE *f, char* name, unsigned char hash[]) {
unsigned char buf[32768];
unsigned long sum1, sum2;
unsigned long len;
unsigned long i;
unsigned long c1, k1, k2;
unsigned long t1, t2, t3, t4, t5, t6;
unsigned int n;
long clen = CKSUM_LENGTH;
long left = len - CKSUM_START;
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len < CKSUM_END) {
if (len < CKSUM_START) {
fprintf(stderr, "%s: is too short to checksum\n", name);
exit(1);
} else if ( (len & 3) != 0 ) {
fprintf(stderr, "%s: length isn't a multiple of 4 bytes\n", name);
exit(1);
}
}
fseek(f, CKSUM_START, SEEK_SET);
t1 = t2 = t3 = t4 = t5 = t6 = CKSUM_STARTVAL;
clen = CKSUM_LENGTH;
left = len - CKSUM_START;
while(clen > 0) {
n = fread(buf, 1, clen < sizeof buf ? clen: sizeof buf, f);
if ( (n == 0) || ((n&3) != 0) ) {
if ( (clen != 0) || (n != 0) ){
fprintf(stderr, "%s: short read\n", name);
exit(1);
}
}
for ( i = 0 ; i < n ; i += 4 ) {
c1 = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];
k1 = t6 + c1;
if (k1 < t6) t4++;
t6 = k1;
t3 ^= c1;
k2 = c1 & 0x1f;
k1 = ROL(c1, k2);
t5 += k1;
if (c1 < t2) {
t2 ^= k1;
} else {
t2 ^= t6 ^ c1;
}
t1 += c1 ^ t5;
}
left -= n;
clen -= n;
}
sum1 = t6 ^ t4 ^ t3;
sum2 = t5 ^ t2 ^ t1;
hash[0] = sum1 >> 24;
hash[1] = sum1 >> 16;
hash[2] = sum1 >> 8;
hash[3] = sum1;
hash[4] = sum2 >> 24;
hash[5] = sum2 >> 16;
hash[6] = sum2 >> 8;
hash[7] = sum2;
}
int
main(int argc, char* argv[]) {
FILE* fp;
unsigned char hash[8];
if (argc != 2) {
fprintf(stderr, "Usage: makemask rom\n");
return 1;
}
if ((fp = fopen(argv[1], "r+b")) == 0) {
perror(argv[1]);
return 1;
}
/* compute hash */
calc3(fp, argv[1], hash);
/* write hash */
fseek(fp, 16, SEEK_SET);
fwrite(hash, sizeof hash, 1, fp);
/* add bootstrap code */
fseek(fp, 64, SEEK_SET);
fwrite(boot_image, 1, 4032, fp);
fclose(fp);
return 0;
}