summaryrefslogtreecommitdiff
path: root/sys/src/cmd/bitsy/bitsyload.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/bitsy/bitsyload.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/bitsy/bitsyload.c')
-rwxr-xr-xsys/src/cmd/bitsy/bitsyload.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/sys/src/cmd/bitsy/bitsyload.c b/sys/src/cmd/bitsy/bitsyload.c
new file mode 100755
index 000000000..a7c6d5801
--- /dev/null
+++ b/sys/src/cmd/bitsy/bitsyload.c
@@ -0,0 +1,130 @@
+#include <u.h>
+#include <libc.h>
+
+enum
+{
+ Magic= 0x5a5abeef,
+};
+
+typedef struct Method Method;
+struct Method {
+ char *verb;
+ char *part;
+ char *file;
+};
+
+Method method[] =
+{
+ { "k", "/dev/flash/kernel", "/sys/src/9/bitsy/9bitsy" },
+ { "r", "/dev/flash/ramdisk", "/sys/src/9/bitsy/paqdisk" },
+ { "u", "/dev/flash/user", "/sys/src/9/bitsy/user" },
+};
+
+void
+leputl(uchar *p, ulong x)
+{
+ *p++ = x;
+ *p++ = x>>8;
+ *p++ = x>>16;
+ *p = x>>24;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s k|r [file]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ char *file;
+ int ctl, in, out;
+ int i, n;
+ uchar *buf;
+ char ctlfile[64];
+ char ctldata[1024];
+ char *args[10];
+ Dir *d;
+ ulong nsects, sectsize;
+ Method *m;
+
+ ARGBEGIN {
+ } ARGEND;
+
+ if(argc == 0)
+ usage();
+
+ for(m = method; m < method + nelem(method); m++)
+ if(strcmp(argv[0], m->verb) == 0)
+ break;
+ if(m == method + nelem(method))
+ usage();
+
+ if(argc < 2)
+ file = m->file;
+ else
+ file = argv[1];
+
+ in = open(file, OREAD);
+ if(in < 0)
+ sysfatal("%s: %r", file);
+ d = dirfstat(in);
+ if(d == nil)
+ sysfatal("stating %s: %r", file);
+
+ out = open(m->part, OWRITE);
+ if(out < 0)
+ sysfatal("%s: %r", m->part);
+ sprint(ctlfile, "%sctl", m->part);
+ ctl = open(ctlfile, ORDWR);
+ if(ctl < 0)
+ sysfatal("%s: %r", ctlfile);
+
+ i = read(ctl, ctldata, sizeof(ctldata) - 1);
+ if (i <= 0)
+ sysfatal("%s: %r", ctlfile);
+ ctldata[i] = '\0';
+ i = tokenize(ctldata, args, nelem(args));
+ if(i < 7)
+ sysfatal("bad flash geometry");
+
+ nsects = atoi(args[5]);
+ sectsize = atoi(args[6]);
+ if(nsects < 3)
+ sysfatal("unreasonable value for nsects: %lud", nsects);
+ if(sectsize < 512)
+ sysfatal("unreasonable value for sectsize: %lud", sectsize);
+
+ /* allocate a buffer and read in the whole file */
+ n = d->length;
+ buf = malloc(n + sectsize);
+ if(buf == nil)
+ sysfatal("not enough room to read in file: %r");
+
+ print("reading %d bytes of %s\n", n, file);
+ if(readn(in, buf, n) != n)
+ sysfatal("error reading file: %r");
+ close(in);
+
+ memset(buf + n, 0, sectsize);
+ n = ((n+sectsize-1)/sectsize)*sectsize;
+
+ if (nsects * sectsize < n)
+ sysfatal("file too large (%d) for partition (%lud)", n, nsects * sectsize);
+
+ print("erasing %s\n", m->part);
+ if(fprint(ctl, "erase") < 0)
+ sysfatal("erase %s: %r", ctlfile);
+ close(ctl);
+ print("writing %s\n", m->part);
+
+ for (i = 0; i < n; i += sectsize)
+ if(write(out, buf + i, sectsize) != sectsize)
+ sysfatal("writing %s at %d: %r", file, i);
+
+ print("write done\n");
+ close(in);
+ close(out);
+}