summaryrefslogtreecommitdiff
path: root/os/boot/mpc/dload.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /os/boot/mpc/dload.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'os/boot/mpc/dload.c')
-rw-r--r--os/boot/mpc/dload.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/os/boot/mpc/dload.c b/os/boot/mpc/dload.c
new file mode 100644
index 00000000..c05423a2
--- /dev/null
+++ b/os/boot/mpc/dload.c
@@ -0,0 +1,103 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+
+static char *kernelfile = "/power/ipaq";
+ulong crc32(void *buf, int n, ulong crc);
+
+void
+main(int argc, char **argv)
+{
+ int ifd, n;
+ char buf[64], reply[1];
+ int i, execsize;
+ Fhdr f;
+ ulong csum;
+
+ ARGBEGIN{
+ }ARGEND
+ ifd = open(kernelfile, OREAD);
+ if(ifd < 0){
+ fprint(2, "dload: can't open %s: %r\n", kernelfile);
+ exits("open");
+ }
+ i = 0;
+ if(crackhdr(ifd, &f) == 0){
+ fprint(2, "dload: not an executable file: %r\n");
+ exits("format");
+ }
+ if(f.magic != Q_MAGIC){
+ fprint(2, "dload: not a powerpc executable\n");
+ exits("format");
+ }
+ execsize = f.txtsz + f.datsz + f.txtoff;
+ seek(ifd, 0, 0);
+ csum = ~0;
+ while(execsize > 0 && (n = read(ifd, buf, sizeof(buf))) > 0){
+ if(n > execsize)
+ n = execsize;
+ for(;;){
+ if(write(1, buf, sizeof(buf)) != sizeof(buf)){ /* always writes full buffer */
+ fprint(2, "dload: write error: %r\n");
+ exits("write");
+ }
+ if(read(0, reply, 1) != 1){
+ fprint(2, "dload: bad reply\n");
+ exits("read");
+ }
+ if(reply[0] != 'n')
+ break;
+ fprint(2, "!");
+ }
+ if(reply[0] != 'y'){
+ fprint(2, "dload: bad ack: %c\n", reply[0]);
+ exits("reply");
+ }
+ if(++i%10 == 0)
+ fprint(2, ".");
+ execsize -= n;
+ }
+ exits(0);
+}
+
+/*
+ * from Rob Warnock
+ */
+static ulong crc32tab[256]; /* initialised on first call to crc32 */
+
+enum {
+ CRC32POLY = 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */
+};
+
+/*
+ * Build auxiliary table for parallel byte-at-a-time CRC-32.
+ */
+static void
+initcrc32(void)
+{
+ int i, j;
+ ulong c;
+
+ for(i = 0; i < 256; i++) {
+ for(c = i << 24, j = 8; j > 0; j--)
+ if(c & (1<<31))
+ c = (c<<1) ^ CRC32POLY;
+ else
+ c <<= 1;
+ crc32tab[i] = c;
+ }
+}
+
+ulong
+crc32(void *buf, int n, ulong crc)
+{
+ uchar *p;
+
+ if(crc32tab[1] == 0)
+ initcrc32();
+ crc = ~crc;
+ for(p = buf; --n >= 0;)
+ crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
+ return ~crc;
+}