xref: /inferno-os/os/boot/rpcg/dload.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 
6 static	char	*kernelfile = "/power/ipaq";
7 ulong	crc32(void *buf, int n, ulong crc);
8 
9 void
main(int argc,char ** argv)10 main(int argc, char **argv)
11 {
12 	int ifd, n;
13 	char buf[64], reply[1];
14 	int i, execsize;
15 	Fhdr f;
16 	ulong csum;
17 
18 	ARGBEGIN{
19 	}ARGEND
20 	ifd = open(kernelfile, OREAD);
21 	if(ifd < 0){
22 		fprint(2, "dload: can't open %s: %r\n", kernelfile);
23 		exits("open");
24 	}
25 	i = 0;
26 	if(crackhdr(ifd, &f) == 0){
27 		fprint(2, "dload: not an executable file: %r\n");
28 		exits("format");
29 	}
30 	if(f.magic != Q_MAGIC){
31 		fprint(2, "dload: not a powerpc executable\n");
32 		exits("format");
33 	}
34 	execsize = f.txtsz + f.datsz + f.txtoff;
35 	seek(ifd, 0, 0);
36 	csum = ~0;
37 	while(execsize > 0 && (n = read(ifd, buf, sizeof(buf))) > 0){
38 		if(n > execsize)
39 			n = execsize;
40 		for(;;){
41 			if(write(1, buf, sizeof(buf)) != sizeof(buf)){	/* always writes full buffer */
42 				fprint(2, "dload: write error: %r\n");
43 				exits("write");
44 			}
45 			if(read(0, reply, 1) != 1){
46 				fprint(2, "dload: bad reply\n");
47 				exits("read");
48 			}
49 			if(reply[0] != 'n')
50 				break;
51 			fprint(2, "!");
52 		}
53 		if(reply[0] != 'y'){
54 			fprint(2, "dload: bad ack: %c\n", reply[0]);
55 			exits("reply");
56 		}
57 		if(++i%10 == 0)
58 			fprint(2, ".");
59 		execsize -= n;
60 	}
61 	exits(0);
62 }
63 
64 /*
65  * from Rob Warnock
66  */
67 static	ulong	crc32tab[256];	/* initialised on first call to crc32 */
68 
69 enum {
70 	CRC32POLY = 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
71 };
72 
73 /*
74  * Build auxiliary table for parallel byte-at-a-time CRC-32.
75  */
76 static void
initcrc32(void)77 initcrc32(void)
78 {
79 	int i, j;
80 	ulong c;
81 
82 	for(i = 0; i < 256; i++) {
83 		for(c = i << 24, j = 8; j > 0; j--)
84 			if(c & (1<<31))
85 				c = (c<<1) ^ CRC32POLY;
86 			else
87 				c <<= 1;
88 		crc32tab[i] = c;
89 	}
90 }
91 
92 ulong
crc32(void * buf,int n,ulong crc)93 crc32(void *buf, int n, ulong crc)
94 {
95 	uchar *p;
96 
97 	if(crc32tab[1] == 0)
98 		initcrc32();
99 	crc = ~crc;
100 	for(p = buf; --n >= 0;)
101 		crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
102 	return ~crc;
103 }
104