A boot/aux.c => boot/aux.c +144 -0
@@ 0,0 1,144 @@
+#include <u.h>
+#include <libc.h>
+#include <../boot/boot.h>
+
+int
+plumb(char *dir, char *dest, int *efd, char *here)
+{
+ char buf[128];
+ char name[128];
+ int n;
+
+ sprint(name, "%s/clone", dir);
+ efd[0] = open(name, ORDWR);
+ if(efd[0] < 0)
+ return -1;
+ n = read(efd[0], buf, sizeof(buf)-1);
+ if(n < 0){
+ close(efd[0]);
+ return -1;
+ }
+ buf[n] = 0;
+ sprint(name, "%s/%s/data", dir, buf);
+ if(here){
+ sprint(buf, "announce %s", here);
+ if(sendmsg(efd[0], buf) < 0){
+ close(efd[0]);
+ return -1;
+ }
+ }
+ sprint(buf, "connect %s", dest);
+ if(sendmsg(efd[0], buf) < 0){
+ close(efd[0]);
+ return -1;
+ }
+ efd[1] = open(name, ORDWR);
+ if(efd[1] < 0){
+ close(efd[0]);
+ return -1;
+ }
+ return efd[1];
+}
+
+int
+sendmsg(int fd, char *msg)
+{
+ int n;
+
+ n = strlen(msg);
+ if(write(fd, msg, n) != n)
+ return -1;
+ return 0;
+}
+
+void
+warning(char *s)
+{
+ char buf[ERRLEN];
+
+ errstr(buf);
+ fprint(2, "boot: %s: %s\n", s, buf);
+}
+
+void
+fatal(char *s)
+{
+ char buf[ERRLEN];
+
+ errstr(buf);
+ fprint(2, "boot: %s: %s\n", s, buf);
+ exits(0);
+}
+
+int
+readenv(char *name, char *buf, int len)
+{
+ int f, n;
+ char ename[2*NAMELEN];
+
+ sprint(ename, "#e/%s", name);
+ buf[0] = 0;
+ f = open(ename, OREAD);
+ if(f < 0)
+ return -1;
+ n = read(f, buf, len-1);
+ if(n >= 0)
+ buf[n] = 0;
+ close(f);
+ return 0;
+}
+
+void
+setenv(char *name, char *val)
+{
+ int f;
+ char ename[2*NAMELEN];
+
+ sprint(ename, "#e/%s", name);
+ f = create(ename, 1, 0666);
+ if(f < 0)
+ return;
+ write(f, val, strlen(val));
+ close(f);
+}
+
+void
+srvcreate(char *name, int fd)
+{
+ char *srvname;
+ int f;
+
+ srvname = strrchr(name, '/');
+ if(srvname)
+ srvname++;
+ else
+ srvname = name;
+
+ sprint(buf, "#s/%s", srvname);
+ f = create(buf, 1, 0666);
+ if(f < 0)
+ fatal(buf);
+ sprint(buf, "%d", fd);
+ if(write(f, buf, strlen(buf)) != strlen(buf))
+ fatal("write");
+ close(f);
+}
+
+int
+outin(char *prompt, char *def, int len)
+{
+ int n;
+ char buf[256];
+
+ do{
+ print("%s[%s]: ", prompt, *def ? def : "no default");
+ n = read(0, buf, len);
+ }while(n==0);
+ if(n < 0)
+ fatal("can't read #c/cons; please reboot");
+ if(n != 1){
+ buf[n-1] = 0;
+ strcpy(def, buf);
+ }
+ return n;
+}
A boot/boot.c => boot/boot.c +327 -0
@@ 0,0 1,327 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include "../port/bootp.h"
+#include "../port/arp.h"
+
+#define DEFSYS "bootes"
+typedef struct Net Net;
+typedef struct Flavor Flavor;
+
+enum
+{
+ Nterm = 4,
+ CtrlD = 4,
+ Cr = 13,
+ View = 0x80,
+};
+
+Fcall hdr;
+int printcol;
+
+char cputype[NAMELEN];
+char terminal[NAMELEN];
+char sys[2*NAMELEN];
+char username[NAMELEN];
+
+int mflag;
+int fflag;
+int kflag;
+
+void nop(int);
+void session(int);
+int cache(int);
+void swapproc(void);
+void settime(int);
+Method *rootserver(char*);
+
+void
+main(int argc, char *argv)
+{
+ int fd;
+ Method *mp;
+ char cmd[64];
+ char flags[5];
+ int islocal;
+
+ sleep(1000);
+
+ open("#c/cons", OREAD);
+ open("#c/cons", OWRITE);
+ open("#c/cons", OWRITE);
+
+ ARGBEGIN{
+ case 'u':
+ strcpy(username, ARGF());
+ break;
+ case 'k':
+ kflag = 1;
+ break;
+ case 'm':
+ mflag = 1;
+ break;
+ case 'f':
+ fflag = 1;
+ break;
+ }ARGEND
+
+ readenv("cputype", cputype, sizeof(cputype));
+ readenv("terminal", terminal, sizeof(cputype));
+
+ /*
+ * pick a method and initialize it
+ */
+ mp = rootserver(*argv);
+ islocal = strcmp(mp->name, "local") == 0;
+ (*mp->config)(mp);
+
+ /*
+ * get/set key or password
+ */
+ (*pword)(mp);
+
+ /*
+ * connect to the root file system
+ */
+ fd = (*mp->connect)();
+ if(fd < 0)
+ fatal("can't connect to file server");
+ if(!islocal){
+ nop(fd);
+ session(fd);
+ fd = cache(fd);
+ srvcreate(sys, fd);
+ }
+ srvcreate("boot", fd);
+
+ /*
+ * create the name space, mount the root fs
+ */
+ if(bind("/", "/", MREPL) < 0)
+ fatal("bind");
+ if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
+ fatal("mount");
+ close(fd);
+
+ /*
+ * start local fs if its not the root file server
+ */
+ if(!islocal){
+ for(mp = method; mp->name; mp++)
+ if(strcmp(mp->name, "local")==0){
+ local = (*mp->connect)(mp);
+ if(local < 0)
+ break;
+ if(mount(local, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
+ fatal("mount");
+ close(local);
+ break;
+ }
+ }
+
+ settime(islocal);
+ swapproc();
+
+ sleep(1000);
+ sprint(cmd, "/%s/init", cputype);
+ sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m", "");
+ execl(cmd, "init", flags, 0);
+ fatal(cmd);
+}
+
+/*
+ * ask user from whence comes the root file system
+ */
+Method*
+rootserver(char *arg)
+{
+ char prompt[256];
+ char reply[64];
+ Method *mp;
+ char *cp;
+ int n;
+
+ mp = method;
+ n = 0;
+ sprint(prompt, "root is from (", mp->name);
+ for(mp++; mp->name; mp++)
+ n += sprint(prompt+n, ", %s", mp->name);
+ sprint(prompt+n, ")");
+
+ for(;;){
+ strcpy(reply, method->name);
+ if(arg == 0)
+ outin(prompt, reply, sizeof(reply));
+ else
+ strcpy(reply, arg);
+ arg = 0;
+ for(mp = method; mp->name; mp++)
+ if(*reply == *mp->name){
+ cp = strchr(reply, '!');
+ if(cp)
+ strcpy(sys, cp+1);
+ return mp;
+ }
+ if(mp->name == 0)
+ continue;
+ }
+}
+
+void
+nop(int fd)
+{
+ long n;
+
+ print("nop...");
+ hdr.type = Tnop;
+ hdr.tag = NOTAG;
+ n = convS2M(&hdr, buf);
+ if(write(fd, buf, n) != n)
+ fatal("write nop");
+ n = read(fd, buf, sizeof buf);
+ if(n==2 && buf[0]=='O' && buf[1]=='K')
+ n = read(fd, buf, sizeof buf);
+ if(n <= 0)
+ fatal("read nop");
+ if(convM2S(buf, &hdr, n) == 0) {
+ print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n",
+ n, buf[0], buf[1], buf[2], buf[3]);
+ fatal("format nop");
+ }
+ if(hdr.type != Rnop)
+ fatal("not Rnop");
+}
+
+void
+session(int fd)
+{
+ long n;
+
+ print("session...");
+ hdr.type = Tsession;
+ hdr.tag = NOTAG;
+ n = convS2M(&hdr, buf);
+ if(write(fd, buf, n) != n)
+ fatal("write session");
+ n = read(fd, buf, sizeof buf);
+ if(n <= 0)
+ fatal("read session");
+ if(convM2S(buf, &hdr, n) == 0)
+ fatal("format session");
+ if(hdr.type == Rerror){
+ print("error %s;", hdr.ename);
+ fatal(hdr.ename);
+ }
+ if(hdr.type != Rsession)
+ fatal("not Rsession");
+}
+
+int
+cache(int fd)
+{
+ ulong i;
+ int p[2];
+ char d[DIRLEN];
+ char partition[2*NAMELEN];
+
+ if(stat("/cfs", d) < 0)
+ return fd;
+ sprint(partition, "%scache", bootdisk);
+ if(stat(partition, d) < 0)
+ return fd;
+ print("cfs...");
+ if(pipe(p)<0)
+ fatal("pipe");
+ switch(fork()){
+ case -1:
+ fatal("fork");
+ case 0:
+ close(p[1]);
+ dup(fd, 0);
+ close(fd);
+ dup(p[0], 1);
+ close(p[0]);
+ if(format)
+ execl("/cfs", "bootcfs", "-fs", "-p", partition, 0);
+ else
+ execl("/cfs", "bootcfs", "-s", "-p", partition, 0);
+ break;
+ default:
+ close(p[0]);
+ close(fd);
+ fd = p[1];
+ break;
+ }
+ return fd;
+}
+
+void
+swapproc(void)
+{
+ int fd;
+
+ fd = open("#c/swap", OWRITE);
+ if(fd < 0){
+ warning("opening #c/swap");
+ return;
+ }
+ if(write(fd, "start", 5) <= 0)
+ warning("starting swap kproc");
+}
+
+void
+settime(int islocal)
+{
+ int n, f;
+ int timeset;
+ Dir dir;
+ char dirbuf[DIRLEN];
+ char *srvname;
+
+ print("time...");
+ timeset = 0;
+ if(islocal){
+ /*
+ * set the time from the real time clock
+ */
+ f = open("#r/rtc", ORDWR);
+ if(f >= 0){
+ if((n = read(f, dirbuf, sizeof(dirbuf)-1)) > 0){
+ dirbuf[n] = 0;
+ timeset = 1;
+ }
+ close(f);
+ }
+ }
+ if(timeset == 0){
+ /*
+ * set the time from the access time of the root
+ */
+ f = open("#s/boot", ORDWR);
+ if(f < 0)
+ return;
+ if(mount(f, "/n/boot", MREPL, "", "") < 0){
+ close(f);
+ return;
+ }
+ close(f);
+ if(stat("/n/boot", dirbuf) < 0)
+ fatal("stat");
+ convM2D(dirbuf, &dir);
+ sprint(dirbuf, "%ld", dir.atime);
+ unmount(0, "/n/boot");
+ /*
+ * set real time clock if there is one
+ */
+ f = open("#r/rtc", ORDWR);
+ if(f > 0){
+ write(f, dirbuf, strlen(dirbuf));
+ close(f);
+ }
+ close(f);
+ }
+
+ f = open("#c/time", OWRITE);
+ write(f, dirbuf, strlen(dirbuf));
+ close(f);
+}
A boot/boot.h => boot/boot.h +59 -0
@@ 0,0 1,59 @@
+typedef struct Method Method;
+struct Method
+{
+ char *name;
+ void (*config)(Method*);
+ void (*auth)(Method*);
+ void (*connect)(Method*);
+ char *arg;
+};
+
+extern char terminal[NAMELEN];
+extern char sys[2*NAMELEN];
+extern char password[NAMELEN];
+extern char username[NAMELEN];
+extern char cputype[NAMELEN];
+extern char *bootdisk;
+extern char *initflag;
+extern void (*pword)(Method*);
+extern int kflag;
+
+/* libc equivalent */
+extern int plumb(char*, char*, int*, char*);
+extern int outin(char*, char*, int);
+extern int sendmsg(int, char*);
+extern void warning(char*);
+extern void fatal(char*);
+extern int readenv(char*, char*, int);
+extern void setenv(char*, char*);
+extern void srvcreate(char*, int);
+extern int dkauth(void);
+extern int dkconnect(void);
+extern void userpasswd(int);
+extern void getpasswd(char*, int);
+
+/* methods */
+extern void config9600(Method*);
+extern int auth9600(Method*);
+extern int connect9600(Method*);
+extern void config192000(Method*);
+extern int auth192000(Method*);
+extern int connect192000(Method*);
+extern void confighs(Method*);
+extern int authhs(Method*);
+extern int connecths(Method*);
+extern void configincon(Method*);
+extern int authincon(Method*);
+extern int connectincon(Method*);
+extern void configil(Method*);
+extern int authil(Method*);
+extern int connectil(Method*);
+extern void configtcp(Method*);
+extern int authtcp(Method*);
+extern int connecttcp(Method*);
+extern void configcyc(Method*);
+extern int authcyc(Method*);
+extern int connectcyc(Method*);
+extern void configlocal(Method*);
+extern int authlocal(Method*);
+extern int connectlocal(Method*);
A boot/getpasswd.c => boot/getpasswd.c +43 -0
@@ 0,0 1,43 @@
+#include <u.h>
+#include <libc.h>
+#include <../boot/boot.h>
+
+void
+getpasswd(char *p, int len)
+{
+ char c;
+ int i, n, fd;
+
+ fd = open("#c/consctl", OWRITE);
+ if(fd < 0)
+ fatal("can't open consctl; please reboot");
+ write(fd, "rawon", 5);
+ Prompt:
+ print("password: ");
+ n = 0;
+ for(;;){
+ do{
+ i = read(0, &c, 1);
+ if(i < 0)
+ fatal("can't read cons; please reboot");
+ }while(i == 0);
+ switch(c){
+ case '\n':
+ p[n] = '\0';
+ close(fd);
+ print("\n");
+ return;
+ case '\b':
+ if(n > 0)
+ n--;
+ break;
+ case 'u' - 'a' + 1: /* cntrl-u */
+ print("\n");
+ goto Prompt;
+ default:
+ if(n < len - 1)
+ p[n++] = c;
+ break;
+ }
+ }
+}
A boot/key.c => boot/key.c +42 -0
@@ 0,0 1,42 @@
+#include <u.h>
+#include <libc.h>
+#include <../boot/boot.h>
+
+void
+key(Method *mp)
+{
+ char password[20], key[7];
+ int prompt, fd;
+
+ USED(mp);
+
+ prompt = kflag;
+ fd = open("#r/nvram", ORDWR);
+ if(fd < 0){
+ prompt = 1;
+ warning("can't open nvram");
+ }
+ if(prompt){
+ do
+ if(getpasswd(password, sizeof password) < 0){
+ warning("can't read cons");
+ return;
+ }
+ while(!passtokey(key, password, strlen(password)));
+ }else if(seek(fd, 1024+900, 0) < 0 || read(fd, key, 7) != 7){
+ close(fd);
+ warning("can't read key from nvram");
+ }
+ if(kflag && seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7){
+ close(fd);
+ warning("can't write key to nvram");
+ }
+ close(fd);
+ fd = open("#c/key", OWRITE);
+ if(fd < 0)
+ warning("can't open key");
+ else if(write(fd, key, 7) != 7)
+ warning("can't write key");
+ close(fd);
+}
+
A boot/local.c => boot/local.c +57 -0
@@ 0,0 1,57 @@
+#include <u.h>
+#include <libc.h>
+#include <../boot/boot.h>
+
+static char *disk;
+
+void
+configlocal(Method *mp)
+{
+ disk = mp->arg;
+ USED(mp);
+}
+
+int
+authlocal(void)
+{
+ return -1;
+}
+
+int
+connectlocal(void)
+{
+ ulong i;
+ int p[2];
+ char d[DIRLEN];
+ char sbuf[32];
+ char rbuf[32];
+ char *mtpt;
+ char partition[2*NAMELEN];
+
+ if(stat("/kfs", d) < 0)
+ return -1;
+ sprint(partition, "%sfs", mp->arg ? mp->arg : bootdisk);
+ if(stat(partition, d) < 0)
+ return -1;
+
+ if(bind("#c", "/dev", MREPL) < 0)
+ fatal("bind #c");
+ if(bind("#p", "/proc", MREPL) < 0)
+ fatal("bind #p");
+ if(pipe(p)<0)
+ fatal("pipe");
+ switch(fork()){
+ case -1:
+ fatal("fork");
+ case 0:
+ sprint(sbuf, "%d", p[0]);
+ sprint(rbuf, "%d", p[1]);
+ execl("/kfs", "kfs", "-f", partition, "-s", sbuf, rbuf, 0);
+ fatal("can't exec kfs");
+ default:
+ break;
+ }
+
+ close(p[1]);
+ return p[0];
+}
A boot/userpasswd.c => boot/userpasswd.c +92 -0
@@ 0,0 1,92 @@
+#include <u.h>
+#include <libc.h>
+#include <../boot/boot.h>
+
+char password[NAMELEN];
+
+static int
+passtokey(char *key, char *p, int n)
+{
+ uchar t[10];
+ int c;
+
+ memset(t, ' ', sizeof t);
+ if(n < 5)
+ return 0;
+ if(n > 10)
+ n = 10;
+ strncpy((char*)t, p, n);
+ if(n >= 9){
+ c = p[8] & 0xf;
+ if(n == 10)
+ c += p[9] << 4;
+ for(n = 0; n < 8; n++)
+ if(c & (1 << n))
+ t[n] -= ' ';
+ }
+ for(n = 0; n < 7; n++)
+ key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1)));
+ return 1;
+}
+
+/*
+ * get/set user name and password. verify password with auth server.
+ */
+void
+userpasswd(Method *mp)
+{
+ char key[7];
+ char buf[8 + NAMELEN];
+ int fd, crfd;
+
+ if(*username == 0 || strcmp(username, "none") == 0){
+ strcpy(username, "none");
+ outin("user", username, sizeof(username));
+ }
+ crfd = fd = -1;
+ while(strcmp(username, "none") != 0 && strcmp(mp->name, "local") != 0){
+ getpasswd(password, sizeof password);
+ if(!passtokey(key, password, strlen(password))){
+ print("bad password; try again\n");
+ continue;
+ }
+ fd = open("#c/key", OWRITE);
+ if(fd < 0)
+ fatal("can't open #c/key; please reboot");
+ if(write(fd, key, 7) != 7)
+ fatal("can't write #c/key; please reboot");
+ close(fd);
+ crfd = open("#c/crypt", ORDWR);
+ if(crfd < 0)
+ fatal("can't open crypt file");
+ write(crfd, "E", 1);
+ fd = (*mp->auth)();
+ if(fd < 0){
+ warning("password not checked!");
+ break;
+ }
+ strncpy(buf+8, username, NAMELEN);
+ if(read(fd, buf, 8) != 8
+ || write(crfd, buf, 8) != 8
+ || read(crfd, buf, 8) != 8
+ || write(fd, buf, 8 + NAMELEN) != 8 + NAMELEN){
+ warning("password not checked!");
+ break;
+ }
+ if(read(fd, buf, 2) == 2 && buf[0]=='O' && buf[1]=='K')
+ break;
+ close(fd);
+ outin("user", username, sizeof(username));
+ }
+ close(fd);
+ close(crfd);
+
+ /* set user now that we're sure */
+ fd = open("#c/user", OWRITE|OTRUNC);
+ if(fd >= 0){
+ if(write(fd, username, strlen(username)) < 0)
+ warning("write user name");
+ close(fd);
+ }else
+ warning("open #c/user");
+}
M port/devcons.c => port/devcons.c +1 -1
@@ 379,7 379,7 @@ int
readnum(ulong off, char *buf, ulong n, ulong val, int size)
{
char tmp[64];
- Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG };
+ Op op = { tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG };
numbconv(&op, 10);
tmp[size-1] = ' ';
M port/devmnt.c => port/devmnt.c +3 -4
@@ 160,12 160,11 @@ mntattach(char *muxattach)
m->blocksize = MAXFDATA;
switch(devchar[m->c->type]) {
- case 'H': /* Hotrod */
- case '3': /* BIT3 */
- m->mux = 1;
- break;
default:
m->mux = 0;
+ case 'H': /* Cyclone */
+ m->mux = 1;
+ break;
}
incref(m->c);
unlock(m);
M port/page.c => port/page.c +2 -1
@@ 97,7 97,7 @@ addsplit(Region *r, ulong start, ulong end)
* Called to allocate permanent data structures, before calling pageinit().
* We assume all of text+data+bss is in the first memory bank.
*
- * alignment is in number of bytes. It pretains both to the start and
+ * alignment is in number of bytes. It pertains both to the start and
* end of the allocated memory.
*
* If crevasse is specified, no allocation can span an address that is
@@ 195,6 195,7 @@ pageinit(void)
ulong i, vmem, pmem, hw, hr;
Page *p;
+print("addr0 %lux addr1 %lux\n", palloc.addr0, palloc.addr1);
/*
* calculate an upper bound to the number of pages structures
* we'll need (np).
M power/devhotrod.c => power/devhotrod.c +1 -3
@@ 423,9 423,7 @@ hotrodintr(int vec)
if(h->ri >= NRQ)
h->ri = 0;
hm->intr = 1;
- if(hm->abort)
- print("abort wakeup\n");
- else
+ if(!hm->abort)
wakeup(&hm->r);
}
}