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