diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /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-x | sys/src/cmd/bitsy/bitsyload.c | 130 |
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); +} |