No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hp700 / stand / xxboot / iplsum.c
blob4d9236b51e73986498e21094c8019c6defce3cad
1 /* $NetBSD: iplsum.c,v 1.3 2009/03/14 21:04:09 dsl Exp $ */
3 /*
4 * Calculate 32bit checksum of IPL and store in a certain location
6 * Written in 2003 by ITOH Yasufumi (itohy@NetBSD.org).
7 * Public domain
8 */
10 #include <sys/types.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <netinet/in.h>
15 #ifndef __BIT_TYPES_DEFINED__
16 typedef unsigned int u_int32_t;
17 #endif
19 /* see README.ipl */
20 #define IPLOFF (4*1024) /* 4KB */
21 #define IPL1SIZE (4*1024) /* 4KB */
22 #define IPL2SIZE (1*1024) /* 1KB */
23 #define IPL2ONDISK 0x0400
24 #define IPL3SIZE (3*512) /* 1.5KB */
25 #define IPL3ONDISK 0x0A00
26 #define IPLSIZE (IPL1SIZE + IPL2SIZE + IPL3SIZE)
27 #define BOOTSIZE (IPLOFF + IPLSIZE)
28 #define BOOTBLOCKSIZE 8192
30 u_int32_t bootblk[BOOTSIZE / sizeof(u_int32_t) + 1];
32 #define SUMOFF ((IPLOFF + 4) / sizeof(u_int32_t))
34 #ifdef __STDC__
35 int main(int, char *[]);
36 #endif
38 int
39 main(int argc, char *argv[])
41 FILE *fp;
42 int len;
43 u_int32_t sum, *p;
44 int iploff, iplsumsize;
46 if (argc != 3) {
47 fprintf(stderr, "usage: %s <input> <output>\n", argv[0]);
48 return 1;
51 /* read file */
52 if ((fp = fopen(argv[1], "rb")) == NULL) {
53 perror(argv[1]);
54 return 1;
56 if ((len = fread(bootblk, 1, sizeof bootblk, fp)) <= IPLOFF) {
57 fprintf(stderr, "%s: too short\n", argv[1]);
58 return 1;
59 } else if (len > BOOTSIZE) {
60 fprintf(stderr, "%s: too long\n", argv[1]);
61 return 1;
63 (void) fclose(fp);
65 /* sanity check */
66 if ((ntohl(bootblk[0]) & 0xffff0000) != 0x80000000) {
67 fprintf(stderr, "%s: bad LIF magic\n", argv[1]);
68 return 1;
70 iploff = ntohl(bootblk[0xf0 / sizeof(u_int32_t)]);
71 iplsumsize = ntohl(bootblk[0xf4 / sizeof(u_int32_t)]);
72 printf("%d bytes free, ipl offset = %d, ipl sum size = %d\n",
73 BOOTSIZE - len, iploff, iplsumsize);
74 if (iploff != IPLOFF || iplsumsize <= 0 || iplsumsize % 2048 ||
75 iploff + iplsumsize > BOOTBLOCKSIZE) {
76 fprintf(stderr, "%s: bad ipl offset / size\n", argv[1]);
77 return 1;
80 /* checksum */
81 sum = 0;
82 for (p = bootblk + IPLOFF / sizeof(u_int32_t);
83 p < bootblk + (IPLOFF + IPL1SIZE) / sizeof(u_int32_t); p++)
84 sum += ntohl(*p);
86 bootblk[SUMOFF] = htonl(ntohl(bootblk[SUMOFF]) - sum);
88 /* transfer ipl part 2 */
89 memcpy(bootblk + IPL2ONDISK / sizeof(u_int32_t),
90 bootblk + (IPLOFF + IPL1SIZE) / sizeof(u_int32_t),
91 IPL2SIZE);
93 /* transfer ipl part 3 */
94 memcpy(bootblk + IPL3ONDISK / sizeof(u_int32_t),
95 bootblk + (IPLOFF + IPL1SIZE + IPL2SIZE) / sizeof(u_int32_t),
96 IPL3SIZE);
98 /* write file */
99 if ((fp = fopen(argv[2], "wb")) == NULL) {
100 perror(argv[2]);
101 return 1;
103 if ((len = fwrite(bootblk, 1, BOOTBLOCKSIZE, fp)) != BOOTBLOCKSIZE) {
104 if (len < 0)
105 perror(argv[2]);
106 else
107 fprintf(stderr, "%s: short write\n", argv[2]);
108 fclose(fp);
109 (void) remove(argv[2]);
110 return 1;
112 if (fclose(fp)) {
113 perror(argv[2]);
114 (void) remove(argv[2]);
115 return 1;
118 return 0;