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