M boot/boot.c => boot/boot.c +0 -1
@@ 111,7 111,6 @@ main(int argc, char *argv[])
settime(islocal);
swapproc();
- sleep(1000);
sprint(cmd, "/%s/init", cputype);
sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : "");
execl(cmd, "init", flags, 0);
M boot/nopsession.c => boot/nopsession.c +39 -37
@@ 4,53 4,55 @@
#include "../boot/boot.h"
static Fcall hdr;
-static char buf[4*1024];
-void
-nop(int fd)
+static void
+rpc(int fd, int type)
{
- long n;
+ int n, l;
+ char buf[128], *p;
- print("nop...");
- hdr.type = Tnop;
+ hdr.type = type;
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");
+ fatal("write rpc");
+
+ print("...");
+ p = buf;
+ l = 0;
+ while(l < 3) {
+ n = read(fd, p, 3);
+ if(n <= 0)
+ fatal("read rpc");
+ if(n == 2 && l == 0 && buf[0] == 'O' && buf[1] == 'K')
+ continue;
+ p += n;
+ l += n;
+ }
+ if(convM2S(buf, &hdr, n) == 0){
+ print("%ux %ux %ux\n", buf[0], buf[1], buf[2]);
+ fatal("rpc format");
+ }
+ if(hdr.tag != NOTAG)
+ fatal("rpc tag not NOTAG");
+ if(hdr.type == Rerror){
+ print("error %s;", hdr.ename);
+ fatal("remote error");
}
- if(hdr.type != Rnop)
- fatal("not Rnop");
+ if(hdr.type != type+1)
+ fatal("not reply");
}
void
-session(int fd)
+nop(int fd)
{
- long n;
+ print("nop");
+ rpc(fd, Tnop);
+}
- 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");
+void
+session(int fd)
+{
+ print("session");
+ rpc(fd, Tsession);
}
M gnot/lib.h => gnot/lib.h +3 -3
@@ 62,9 62,9 @@ extern int print(char*, ...);
*/
extern long strtol(char*, char**, int);
extern ulong strtoul(char*, char**, int);
-extern long etext;
-extern long edata;
-extern long end;
+extern char etext[];
+extern char edata[];
+extern char end[];
/*
* Syscall data structures
*/
M port/devarp.c => port/devarp.c +2 -0
@@ 286,6 286,8 @@ arpwrite(Chan *c, char *a, long n, ulong offset)
void
arpopn(Queue *q, Stream *s)
{
+ if(Myip[Myself])
+ error(Einuse);
USED(q, s);
}
M port/devcons.c => port/devcons.c +3 -0
@@ 240,6 240,9 @@ echo(Rune r, char *buf, int n)
case 'r':
exit();
break;
+ case 't':
+ tcpdump();
+ break;
}
}else if(r == 0x14){
ctrlt++;
M port/devip.c => port/devip.c +1 -0
@@ 530,6 530,7 @@ tcpstoput(Queue *q, Block *bp)
case Close_wait:
qlock(tcb);
tcb->sndcnt += blen(bp);
+ print("q %d\n", blen(bp));
if(tcb->sndq == 0)
tcb->sndq = bp;
else {
M port/devkprof.c => port/devkprof.c +1 -1
@@ 39,7 39,7 @@ kprofreset(void)
ulong n;
kprof.minpc = KTZERO;
- kprof.maxpc = (ulong)&etext;
+ kprof.maxpc = (ulong)etext;
kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES;
n = kprof.nbuf*SZ;
kprof.buf = ialloc(n, 0);
M port/devlance.c => port/devlance.c +2 -0
@@ 753,10 753,12 @@ lanceup(Etherpkt *p, int len)
*/
if(!canqlock(e))
continue;
+
if(e->q==0 || e->q->next->len>Streamhi || (t!=e->type && e->type!=-1)){
qunlock(e);
continue;
}
+
if(!waserror()){
bp = allocb(len);
memmove(bp->rptr, (uchar *)p, len);
M port/fault.c => port/fault.c +2 -0
@@ 66,6 66,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
switch(type) {
default:
panic("fault");
+ break;
case SG_TEXT:
if(pagedout(*pg)) /* Demand load */
@@ 209,6 210,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
ask = s->flen-soff;
if(ask > BY2PG)
ask = BY2PG;
+
n = (*devtab[c->type].read)(c, kaddr, ask, daddr);
if(n != ask)
error(Eioload);
M port/lib.h => port/lib.h +3 -3
@@ 62,9 62,9 @@ extern int print(char*, ...);
*/
extern long strtol(char*, char**, int);
extern ulong strtoul(char*, char**, int);
-extern long etext;
-extern long edata;
-extern long end;
+extern char etext[];
+extern char edata[];
+extern char end[];
/*
* Syscall data structures
*/
M port/page.c => port/page.c +1 -2
@@ 17,7 17,6 @@ struct Ptealloc
int pages;
}ptealloclk;
-extern long end;
ulong hiaddr;
static Lock pglock;
@@ 115,7 114,7 @@ iallocspan(ulong n, int align, ulong crevasse)
print("ialloc bad\n");
if(palloc.addr0 == 0){
- region[Nregion-2].start = (((ulong)&end)&~KZERO) + conf.base0;
+ region[Nregion-2].start = (((ulong)end)&~KZERO) + conf.base0;
region[Nregion-2].end = conf.base0 + (conf.npage0<<PGSHIFT);
region[Nregion-1].start = conf.base1;
region[Nregion-1].end = conf.base1 + (conf.npage1<<PGSHIFT);
M port/portdat.h => port/portdat.h +2 -0
@@ 603,6 603,8 @@ struct Queue
Rendez r; /* standard place to wait for flow control */
Rendez *rp; /* where flow control wakeups go to */
void *ptr; /* private info for the queue */
+ Proc *pp;
+ Proc *pg;
};
struct Stream
M port/proc.c => port/proc.c +4 -0
@@ 347,6 347,10 @@ wakeup(Rendez *r)
if(p->state != Wakeme)
panic("wakeup: state");
p->r = 0;
+if((p->sched.pc&KZERO) != KZERO){
+ spllo();
+ panic("wakeup");
+}
ready(p);
}
unlock(r);
M port/stfcall.c => port/stfcall.c +1 -0
@@ 109,6 109,7 @@ upstream(Queue *q, ulong len)
for(bp = bl; bp->next; bp = bp->next)
;
bp->flags |= S_DELIM;
+if(bl->rptr[0] == 73) print("fcall Rclunk %d\n", blen(bl));
PUTNEXT(q, bl);
}
M port/stip.c => port/stip.c +3 -2
@@ 405,6 405,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
ushort id;
Block *bl, **l, *last, *prev;
int ovlap, len, fragsize, pktposn;
+ int end;
/* Check lance has handed us a contiguous buffer */
if(bp->next)
@@ 476,7 477,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
bp->next = *l;
*l = bp;
- /* Check to see if suceeding segments overlap */
+ /* Check to see if succeeding segments overlap */
if(bp->next) {
l = &bp->next;
end = BLKFRAG(bp)->foff + BLKFRAG(bp)->flen;
@@ 491,7 492,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
BLKFRAG(*l)->flen -= ovlap;
(*l)->rptr += ovlap;
break;
- }
+ }
last = (*l)->next;
freeb(*l);
*l = last;
M port/stream.c => port/stream.c +60 -6
@@ 8,6 8,8 @@
#include "devtab.h"
#include "fcall.h"
+ulong fpcs[100], refsa[100], refsf[100], apcs[100];
+
enum {
Nclass=4, /* number of block classes */
};
@@ 184,6 186,9 @@ allocb(ulong size)
{
Block *bp;
Bclass *bcp;
+ ulong pc;
+
+ pc = getcallerpc(((uchar*)&size) - sizeof(size));
/*
* map size to class
@@ 207,6 212,25 @@ allocb(ulong size)
bcp->first = bp->next;
if(bcp->first == 0)
bcp->last = 0;
+
+ if(bcp->size == 68) {
+ int i, hole, fnd;
+ fnd = 0;
+ hole = -1;
+ for(i = 0; i < 100; i++) {
+ if(apcs[i] == pc) {
+ refsa[i]++;
+ fnd = 1;
+ break;
+ }
+ if(refsa[i] == 0 && hole<0)
+ hole = i;
+ }
+ if(fnd == 0 && hole>=0) {
+ refsa[hole] = 1;
+ apcs[hole] = pc;
+ }
+ }
qunlock(bcp);
/*
@@ 221,6 245,7 @@ allocb(ulong size)
if(bp->lim-bp->rptr<size && size<4096)
panic("allocb %lux %lux %d %ux %d", bp->lim, bp->rptr,
size, bp->flags, bcp-bclass);
+ bp->pc = pc;
return bp;
}
@@ 236,10 261,21 @@ freeb(Block *bp)
Bclass *bcp;
int x;
ulong pc;
+int i;
pc = getcallerpc(((uchar*)&bp) - sizeof(bp));
if((bp->flags&S_CLASS) >= Nclass) /* Check for double free */
panic("freeb class last(%lux) this(%lux)", bp->pc, pc);
+
+ bcp = &bclass[bp->flags & S_CLASS];
+ if(bcp->size == 68) {
+ for(i = 0; i < 100; i++)
+ if(apcs[i] == bp->pc) {
+ refsf[i]++;
+ fpcs[i] = pc;
+ }
+ }
+
bp->pc = pc;
for(; bp; bp = nbp){
@@ 424,6 460,7 @@ putq(Queue *q, Block *bp)
int delim;
lock(q);
+ q->pp = u->p;
if(q->first)
q->last->next = bp;
else
@@ 536,6 573,7 @@ getq(Queue *q)
Block *bp;
lock(q);
+ q->pg = u->p;
bp = q->first;
if(bp) {
q->first = bp->next;
@@ 1038,6 1076,7 @@ stputq(Queue *q, Block *bp)
delim = 1;
} else {
lock(q);
+ q->pp = u->p;
if(q->first)
q->last->next = bp;
else
@@ 1468,9 1507,10 @@ dumpblocks(Queue *q, char c)
lock(q);
for(bp = q->first; bp; bp = bp->next){
- print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM)?'D':' ');
- for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
- print(" %uo", *cp);
+ print("%c %c%d%c", c, bp->type == M_DATA ? 'd' : 'c',
+ bp->wptr-bp->rptr, (bp->flags&S_DELIM)?'D':' ');
+ for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+30; cp++)
+ print(" %.2x", *cp);
print("\n");
}
unlock(q);
@@ 1483,18 1523,28 @@ dumpqueues(void)
int count, qcount;
Block *bp;
Bclass *bcp;
-
+int i;
print("\n");
qcount = 0;
for(q = qlist; q < qlist + conf.nqueue; q++, q++){
if(!(q->flag & QINUSE))
continue;
qcount++;
- print("%10s %ux R n %d l %d f %ux r %ux", q->info->name, q,
+ print("%10s %ux R n %d l %d f %ux r %ux ",
+ q->info->name, q,
q->nb, q->len, q->flag, &(q->r));
- print(" W n %d l %d f %ux r %ux next %lux put %lux Rz %lux\n",
+ if(q->pg)
+ print("get %d %s ", q->pg->pid, q->pg->text);
+ if(q->pp)
+ print("put %d %s ", q->pp->pid, q->pp->text);
+ print(" W n %d l %d f %ux r %ux next %lux put %lux Rz %lux",
WR(q)->nb, WR(q)->len,
WR(q)->flag, &(WR(q)->r), q->next, q->put, q->rp);
+ if(q->pg)
+ print("get %d %s ", q->pg->pid, q->pg->text);
+ if(q->pp)
+ print("put %d %s ", q->pp->pid, q->pp->text);
+ print("\n");
dumpblocks(q, 'R');
dumpblocks(WR(q), 'W');
}
@@ 1508,4 1558,8 @@ dumpqueues(void)
bcp->made, count);
}
print("\n");
+ for(i = 0; i < 100; i++) {
+ if(refsa[i] != refsf[i])
+ print("%d alloc %lux %d free %lux\n", refsa[i], apcs[i], refsf[i], fpcs[i]);
+ }
}
M port/tcpinput.c => port/tcpinput.c +50 -2
@@ 42,6 42,7 @@ tcp_input(Ipconv *ipc, Block *bp)
Ipaddr source, dest;
char tos;
ushort length;
+ Block *f;
DPRINT("tcp_input.\n");
@@ 290,6 291,7 @@ process:
/* Ignore segment text */
freeb(bp);
break;
+
case Syn_received:
case Established:
case Finwait1:
@@ 298,6 300,13 @@ process:
tcb->rcvcnt += blen(bp);
if(bp)
if(s->readq) {
+ print("bl %d ty %d\n", blen(bp), bp->rptr[0]);
+ for(f = bp; bp->next; f = f->next)
+ ;
+ if((f->flags&S_DELIM) == 0) {
+ print("No delim upstream rcp");
+ f->flags |= S_DELIM;
+ }
PUTNEXT(s->readq, bp);
bp = 0;
}
@@ 347,7 356,9 @@ process:
break;
}
}
- while(tcb->reseq != 0 && seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq)) {
+ while(tcb->reseq != 0) {
+ if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0)
+ break;
get_reseq(tcb, &tos, &seg, &bp, &length);
if(trim(tcb, &seg, &bp, &length) == 0)
goto gotone;
@@ 880,7 891,8 @@ htontcp(Tcp *tcph, Block *data, Tcphdr *ph)
if(data) {
dlen = blen(data);
- if((data = padb(data, hdrlen + TCP_PKT)) == 0)
+ data = padb(data, hdrlen + TCP_PKT);
+ if(data == 0)
return 0;
/* If we collected blocks delimit the end of the chain */
for(bp = data; bp->next; bp = bp->next)
@@ 977,3 989,39 @@ ntohtcp(Tcp *tcph, Block **bpp)
}
return hdrlen;
}
+
+void
+tcpdumpconv(Ipconv *c)
+{
+ if(c->tcpctl.state == Closed)
+ return;
+
+ print("%s %d -> %d.%d.%d.%d/%d snd %d recv %d una %d nxt %d ptr %d wnd %d\n",
+ tcpstate[c->tcpctl.state],
+ c->psrc,
+ fmtaddr(c->dst),
+ c->pdst,
+ c->tcpctl.sndcnt,
+ c->tcpctl.rcvcnt,
+ c->tcpctl.snd.una,
+ c->tcpctl.snd.nxt,
+ c->tcpctl.snd.ptr,
+ c->tcpctl.snd.wnd);
+}
+
+void
+tcpdump(void)
+{
+ Ipifc *ep, *ifp;
+ Ipconv *cp, *ecp;
+ extern Ipifc *ipifc;
+
+ ep = &ipifc[conf.ipif];
+ for(ifp = ipifc; ifp < ep; ifp++)
+ if(strcmp(ifp->name, "TCP") == 0) {
+ ecp = &ifp->connections[conf.ip];
+ for(cp = ifp->connections; cp < ecp; cp++)
+ tcpdumpconv(cp);
+ break;
+ }
+}
M port/tcpoutput.c => port/tcpoutput.c +37 -37
@@ 99,18 99,15 @@ tcp_output(Ipconv *s)
* in sndcnt but don't actually sit in the send queue,
* dupb will return one less than dsize if a FIN needs to be sent.
*/
+ dbp = 0;
if(dsize != 0){
if(dupb(&dbp, sndq, sent, dsize) != dsize) {
seg.flags |= FIN;
dsize--;
}
- DPRINT("dupb: 1st char = %c\n", dbp->rptr[0]);
- } else
- dbp = 0;
+ print("dupb: %d\n", dbp->rptr[0]);
+ }
- /* If the entire send queue will now be in the pipe, set the
- * push flag
- */
if(sent+dsize == qlen)
seg.flags |= PSH;
@@ 157,14 154,33 @@ tcp_output(Ipconv *s)
tcb->rttseq = tcb->snd.ptr;
}
}
- DPRINT("tcp_output: ip_send s%lux a%lux w%lux u%lux\n",
- seg.seq, seg.ack, seg.wnd, seg.up);
-
+ print("snd: %d %x\n", blen(hbp), seg.seq);
PUTNEXT(Ipoutput, hbp);
}
}
void
+tcprxmit(Ipconv *s)
+{
+ Tcpctl *tcb;
+
+ print("tcp! rexmit\n");
+ tcb = &s->tcpctl;
+ qlock(tcb);
+ tcb->flags |= RETRAN|FORCE;
+ tcb->snd.ptr = tcb->snd.una;
+
+ /* Reduce slowstart threshold to half current window */
+ tcb->ssthresh = tcb->cwind / 2;
+ tcb->ssthresh = MAX(tcb->ssthresh,tcb->mss);
+
+ /* Shrink congestion window to 1 packet */
+ tcb->cwind = tcb->mss;
+ tcp_output(s);
+ qunlock(tcb);
+}
+
+void
tcp_timeout(void *arg)
{
Tcpctl *tcb;
@@ 173,11 189,17 @@ tcp_timeout(void *arg)
s = (Ipconv *)arg;
tcb = &s->tcpctl;
- DPRINT("Timer %lux state = %d\n", s, tcb->state);
+ print("Timer %lux state = %d\n", s, tcb->state);
switch(tcb->state){
- case Closed:
- panic("tcptimeout");
+ default:
+ tcb->backoff++;
+ DPRINT("tcp_timeout: retransmit %d %x\n", tcb->backoff, s);
+ if (tcb->backoff >= MAXBACKOFF)
+ close_self(s, Etimedout);
+ else
+ tcprxmit(s);
+ break;
case Time_wait:
close_self(s, 0);
@@ 186,30 208,8 @@ tcp_timeout(void *arg)
case Established:
if(tcb->backoff < MAXBACKOFF)
tcb->backoff++;
- goto retran;
- default:
- tcb->backoff++;
- DPRINT("tcp_timeout: retransmit %d %x\n", tcb->backoff, s);
-
- if (tcb->backoff >= MAXBACKOFF) {
- DPRINT("tcp_timeout: timeout\n");
- close_self(s, Etimedout);
- }
- else {
- retran:
- qlock(tcb);
- tcb->flags |= RETRAN|FORCE;
- tcb->snd.ptr = tcb->snd.una;
-
- /* Reduce slowstart threshold to half current window */
- tcb->ssthresh = tcb->cwind / 2;
- tcb->ssthresh = MAX(tcb->ssthresh,tcb->mss);
-
- /* Shrink congestion window to 1 packet */
- tcb->cwind = tcb->mss;
- tcp_output(s);
- qunlock(tcb);
- }
+ tcprxmit(s);
+ break;
}
}
@@ 239,7 239,7 @@ tcp_acktimer(Ipconv *s)
}
void
-tcprcvwin(Ipconv *s)
+tcprcvwin(Ipconv *s) /* Call with tcb locked */
{
Tcpctl *tcb = &s->tcpctl;
M power/bboot.c => power/bboot.c +157 -434
@@ 1,37 1,6 @@
#include <u.h>
#include <libc.h>
-
-#include <fcall.h>
-
-#define DEFFILE "/mips/9power"
-#define DEFSYS "bit!bootes"
-
-Fcall hdr;
-char *scmd;
-char bootfile[5*NAMELEN];
-char conffile[5*NAMELEN];
-char sys[NAMELEN];
-
-char buf[4*1024];
-
-int fd;
-int cfd;
-int efd;
-
-typedef
-struct address {
- char *name;
- char *cmd;
-} Address;
-
-Address addr[] = {
- { "ross", "connect 020701005eff" },
- { "bootes", "connect 0800690203f3" },
- { "helix", "connect 080069020427" },
- { "spindle", "connect 0800690202df" },
- { "r70", "connect 08002b04265d" },
- { 0 }
-};
+#include "../boot/boot.h"
struct a_out_h {
ulong magic; /* magic and sections */
@@ 56,399 25,162 @@ struct a_out_h {
ulong mystery; /* complete mystery */
} a_out;
-/*
- * predeclared
- */
-int dkdial(char *);
-int nonetdial(char *);
-int bitdial(char *);
-int readseg(int, int, long, long, int);
-int readkernel(int);
+typedef struct Net Net;
+typedef struct Flavor Flavor;
+
+int printcol;
+
+char cputype[NAMELEN];
+char terminal[NAMELEN];
+char sys[2*NAMELEN];
+char username[NAMELEN];
+char conffile[2*NAMELEN];
+char sysname[2*NAMELEN];
+char buf[8*1024];
+
+int mflag;
+int fflag;
+int kflag;
+
+int cache(int);
+Method *rootserver(char*);
int readconf(int);
-int outin(char *, char *, int);
-void prerror(char *);
-void error(char *);
-void boot(int, char *);
+void readkernel(int);
+int readseg(int, int, long, long, int);
/*
- * usage: 9b [-a] [server] [file]
- *
- * default server is `bitbootes', default file is `/sys/src/9/mips/9'
+ * default boot file
*/
+#define DEFFILE "/mips/9power"
+
+void
main(int argc, char *argv[])
{
- int i;
- char *sysname;
-
- open("#c/cons", 0);
- open("#c/cons", 1);
- open("#c/cons", 1);
-
- sysname = argv[0];
-
- argv++;
- argc--;
- while(argc > 0){
- if(argv[0][0] == '-'){
- argc--;
- argv++;
- } else
- break;
- }
-
- strcpy(sys, DEFSYS);
- strcpy(bootfile, DEFFILE);
- switch(argc){
- case 1:
- strcpy(bootfile, argv[0]);
- break;
- case 2:
- strcpy(bootfile, argv[0]);
- strcpy(sys, argv[1]);
- break;
- }
-
- boot(0, sysname);
- for(;;){
- if(fd > 0)
- close(fd);
- if(cfd > 0)
- close(cfd);
- fd = cfd = 0;
- boot(1, sysname);
- }
-}
+ int fd;
+ Method *mp;
+ char cmd[64];
+ char flags[6];
+ int islocal;
+ char *bootfile;
-int
-bitdial(char *arg)
-{
- return open("#3/bit3", ORDWR);
-}
+ sleep(1000);
-int
-nonetdial(char *arg)
-{
- int efd, cfd, fd;
- Address *a;
- static int mounted;
+ open("#c/cons", OREAD);
+ open("#c/cons", OWRITE);
+ open("#c/cons", OWRITE);
- for(a = addr; a->name; a++){
- if(strcmp(a->name, arg) == 0)
- break;
- }
- if(a->name == 0){
- print("can't convert nonet address to ether address\n");
- return -1;
- }
+ ARGBEGIN{
+ case 'u':
+ strcpy(username, ARGF());
+ break;
+ case 'k':
+ kflag = 1;
+ break;
+ case 'm':
+ mflag = 1;
+ break;
+ case 'f':
+ fflag = 1;
+ break;
+ }ARGEND
- if(!mounted){
- /*
- * grab a lance channel, make it recognize ether type 0x900,
- * and push the nonet ethernet multiplexor onto it.
- */
- efd = open("#l/1/ctl", 2);
- if(efd < 0){
- prerror("opening #l/1/ctl");
- return -1;
- }
- if(write(efd, "connect 0x900", sizeof("connect 0x900")-1)<0){
- close(efd);
- prerror("connect 0x900");
- return -1;
- }
- if(write(efd, "push noether", sizeof("push noether")-1)<0){
- close(efd);
- prerror("push noether");
- return -1;
- }
- if(write(efd, "config nonet", sizeof("config nonet")-1)<0){
- close(efd);
- prerror("config nonet");
- return -1;
- }
- mounted = 1;
- }
+ readenv("cputype", cputype, sizeof(cputype));
+ readenv("terminal", terminal, sizeof(cputype));
+ readenv("sysname", sysname, sizeof(sysname));
+ if(argc > 1)
+ bootfile = argv[1];
+ else
+ bootfile = DEFFILE;
/*
- * grab a nonet channel and call up the file server
+ * pick a method and initialize it
*/
- fd = open("#nnonet/2/data", 2);
- if(fd < 0) {
- prerror("opening #nnonet/2/data");
- return -1;
- }
- cfd = open("#nnonet/2/ctl", 2);
- if(cfd < 0){
- close(fd);
- fd = -1;
- prerror("opening #nnonet/2/ctl");
- return -1;
- }
- if(write(cfd, a->cmd, strlen(a->cmd))<0){
- close(cfd);
- close(fd);
- cfd = fd = -1;
- prerror(a->cmd);
- return -1;
- }
- return fd;
-}
-
-int
-dkdial(char *arg)
-{
- int fd;
- char cmd[64];
- static int mounted;
-
- if(!mounted){
- /*
- * grab the hsvme and configure it for a datakit
- */
- efd = open("#h/ctl", 2);
- if(efd < 0){
- prerror("opening #h/ctl");
- return -1;
- }
- if(write(efd, "push dkmux", sizeof("push dkmux")-1)<0){
- close(efd);
- prerror("push dkmux");
- return -1;
- }
- if(write(efd, "config 4 256 restart dk", sizeof("config 4 256 restart dk")-1)<0){
- close(efd);
- prerror("config 4 256 restart dk");
- return -1;
- }
- mounted = 1;
- sleep(2000); /* wait for things to settle down */
- }
+ mp = rootserver(argc ? *argv : 0);
+ (*mp->config)(mp);
+ islocal = strcmp(mp->name, "local") == 0;
/*
- * grab a datakit channel and call up the file server
+ * connect to the root file system
*/
- fd = open("#k/dk/5/data", 2);
- if(fd < 0) {
- prerror("opening #k/dk/5/data");
- return -1;
- }
- cfd = open("#k/dk/5/ctl", 2);
- if(cfd < 0){
- close(fd);
- fd = -1;
- prerror("opening #k/dk/5/ctl");
- return -1;
- }
- sprint(cmd, "connect %s", arg);
- if(write(cfd, cmd, strlen(cmd))<0){
- close(cfd);
- close(fd);
- cfd = fd = -1;
- prerror(cmd);
- return -1;
- }
- return fd;
-}
-
-void
-boot(int ask, char *addr)
-{
- int n, tries;
- char *srvname;
-
- if(ask){
- outin("bootfile", bootfile, sizeof(bootfile));
- outin("server", sys, sizeof(sys));
- }
-
- for(tries = 0; tries < 5; tries++){
- fd = -1;
- if(strncmp(sys, "bit!", 4) == 0)
- fd = bitdial(srvname = &sys[4]);
- else if(strncmp(sys, "dk!", 3) == 0)
- fd = dkdial(srvname = &sys[3]);
- else if(strncmp(sys, "nonet!", 6) == 0)
- fd = nonetdial(srvname = &sys[6]);
- else
- fd = nonetdial(srvname = sys);
- if(fd >= 0)
- break;
- print("can't connect, retrying...\n");
- sleep(1000);
- }
- if(fd < 0){
- print("can't connect\n");
- return;
- }
-
- print("nop...");
- hdr.type = Tnop;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n){
- print("n = %d\n", n);
- prerror("write nop");
- return;
- }
- reread:
- n = read(fd, buf, sizeof buf);
- if(n <= 0){
- prerror("read nop");
- return;
- }
- if(n == 2)
- goto reread;
- if(convM2S(buf, &hdr, n) == 0) {
- print("n = %d; buf = %.2x %.2x %.2x %.2x\n",
- n, buf[0], buf[1], buf[2], buf[3]);
- prerror("format nop");
- return;
- }
- if(hdr.type != Rnop){
- prerror("not Rnop");
- return;
- }
- if(hdr.tag != NOTAG){
- prerror("tag not NOTAG");
- return;
- }
-
- print("session...");
- hdr.type = Tsession;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n){
- prerror("write session");
- return;
- }
- n = read(fd, buf, sizeof buf);
- if(n <= 0){
- prerror("read session");
- return;
- }
- if(convM2S(buf, &hdr, n) == 0){
- prerror("format session");
- return;
- }
- if(hdr.tag != NOTAG){
- prerror("tag not NOTAG");
- return;
- }
- if(hdr.type == Rerror){
- fprint(2, "boot: error %s\n", hdr.ename);
- return;
- }
- if(hdr.type != Rsession){
- prerror("not Rsession");
- return;
+ fd = (*mp->connect)();
+ if(fd < 0)
+ fatal("can't connect to file server");
+ if(!islocal){
+ nop(fd);
+ session(fd);
+ if(cfs)
+ fd = (*cfs)(fd);
}
- print("mount...");
- if(bind("/", "/", MREPL) < 0){
- prerror("bind");
- return;
- }
- if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0){
- prerror("mount");
- return;
- }
+ /*
+ * create the name space, mount the root fs
+ */
+ if(bind("/", "/", MREPL) < 0)
+ fatal("bind");
+ if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
+ fatal("mount");
close(fd);
- sprint(conffile, "/mips/conf/%s", addr);
+ /*
+ * open the configuration file and read it
+ * into the kernel
+ */
+ sprint(conffile, "/mips/conf/%s", sysname);
print("%s...", conffile);
- while((fd = open(conffile, OREAD)) < 0){
+ while((fd = open(conffile, OREAD)) < 0)
outin("conffile", conffile, sizeof(conffile));
- }
if(readconf(fd) < 0)
- prerror("readconf");
+ fatal("readconf");
close(fd);
+ /*
+ * read in real kernel
+ */
print("%s...", bootfile);
- while((fd = open(bootfile, OREAD)) < 0){
+ while((fd = open(bootfile, OREAD)) < 0)
outin("bootfile", bootfile, sizeof(bootfile));
- }
readkernel(fd);
- prerror("couldn't read kernel");
-}
-
-/*
- * print error
- */
-void
-prerror(char *s)
-{
- char buf[64];
-
- errstr(buf);
- fprint(2, "boot: %s: %s\n", s, buf);
-}
-
-/*
- * print error and exit
- */
-void
-error(char *s)
-{
- char buf[64];
-
- errstr(buf);
- fprint(2, "boot: %s: %s\n", s, buf);
- exits(0);
+ fatal("couldn't read kernel");
}
/*
- * lookup the address for a system
+ * ask user from whence cometh the root file system
*/
-Address *
-lookup(char *arg)
+Method*
+rootserver(char *arg)
{
- Address *a;
+ char prompt[256];
+ char reply[64];
+ Method *mp;
+ char *cp;
+ int n;
- if(strcmp(arg, "?")==0 || strcmp(arg, "help")==0){
- for(a = addr; a->name; a++)
- print("%s\n", a->name);
- return 0;
- }
- for(a = addr; a->name; a++){
- if(strcmp(a->name, arg) == 0)
- return a;
- }
- return 0;
-}
+ mp = method;
+ n = sprint(prompt, "root is from (%s", mp->name);
+ for(mp++; mp->name; mp++)
+ n += sprint(prompt+n, ", %s", mp->name);
+ sprint(prompt+n, ")");
-/*
- * read a segment into memory
- */
-int
-readseg(int in, int out, long inoff, long outoff, int len)
-{
- long n, i;
-
- if(seek(in, inoff, 0) < 0){
- prerror("seeking bootfile");
- return -1;
- }
- if(seek(out, outoff, 0) != outoff){
- prerror("seeking #b/mem");
- return -1;
- }
- for(; len > 0; len -= n){
- if((n = read(in, buf, sizeof buf)) <= 0){
- prerror("reading bootfile");
- return -1;
- }
- if(write(out, buf, n) != n){
- prerror("writing #b/mem");
- return -1;
- }
+ if(arg)
+ strcpy(reply, arg);
+ else
+ strcpy(reply, method->name);
+ for(;;){
+ if(arg == 0 || mflag)
+ outin(prompt, reply, sizeof(reply));
+ 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;
}
- return 0;
}
-/*
- * set a configuration value
- */
-
/*
* read the configuration
@@ 472,10 204,8 @@ readconf(int fd)
* write into 4 meg - 4k
*/
bfd = open("#b/mem", OWRITE);
- if(bfd < 0){
- prerror("can't open #b/mem");
- return;
- }
+ if(bfd < 0)
+ fatal("can't open #b/mem");
x = 0x80000000 | 4*1024*1024 - 4*1024;
if(seek(bfd, x, 0) != x){
close(bfd);
@@ 489,76 219,69 @@ readconf(int fd)
close(bfd);
return 0;
}
+
/*
* read the kernel into memory and jump to it
*/
-int
+void
readkernel(int fd)
{
int n;
int bfd;
bfd = open("#b/mem", OWRITE);
- if(bfd < 0){
- prerror("can't open #b/mem");
- return;
- }
+ if(bfd < 0)
+ fatal("can't open #b/mem");
n = read(fd, &a_out, sizeof(a_out));
- if(n <= 0){
- prerror("can't read boot file");
- close(bfd);
- return;
- }
+ if(n <= 0)
+ fatal("can't read boot file");
print("\n%d", a_out.text);
- if(readseg(fd, bfd, 20*4, a_out.textva, a_out.text)<0){
- prerror("can't read boot file");
- close(bfd);
- return;
- }
+ if(readseg(fd, bfd, 20*4, a_out.textva, a_out.text)<0)
+ fatal("can't read boot file");
print("+%d", a_out.data);
- if(readseg(fd, bfd, 20*4 + a_out.text, a_out.textva + a_out.text, a_out.data)<0){
- prerror("can't read boot file");
- close(bfd);
- return;
- }
+ if(readseg(fd, bfd, 20*4 + a_out.text, a_out.textva + a_out.text, a_out.data)<0)
+ fatal("can't read boot file");
print("+%d", a_out.bss);
close(bfd);
bfd = open("#b/boot", OWRITE);
- if(bfd < 0){
- prerror("can't open #b/boot");
- return;
- }
+ if(bfd < 0)
+ fatal("can't open #b/boot");
print(" entry: 0x%ux\n", a_out.entryva);
sleep(1000);
- if(write(bfd, &a_out.entryva, sizeof a_out.entryva) != sizeof a_out.entryva){
- prerror("can't start kernel");
- close(bfd);
- }
-
- return;
+ if(write(bfd, &a_out.entryva, sizeof a_out.entryva) != sizeof a_out.entryva)
+ fatal("can't start kernel");
}
/*
- * prompt and get input
+ * read a segment into memory
*/
int
-outin(char *prompt, char *def, int len)
+readseg(int in, int out, long inoff, long outoff, int len)
{
- int n;
+ long n, i;
- do{
- print("%s[%s]: ", prompt, def);
- n = read(0, buf, len);
- }while(n==0);
- if(n < 0)
- error("can't read #c/cons; please reboot");
- if(n != 1){
- buf[n-1] = 0;
- strcpy(def, buf);
+ if(seek(in, inoff, 0) < 0){
+ warning("seeking bootfile");
+ return -1;
}
- return n;
+ if(seek(out, outoff, 0) != outoff){
+ warning("seeking #b/mem");
+ return -1;
+ }
+ for(; len > 0; len -= n){
+ if((n = read(in, buf, sizeof buf)) <= 0){
+ warning("reading bootfile");
+ return -1;
+ }
+ if(write(out, buf, n) != n){
+ warning("writing #b/mem");
+ return -1;
+ }
+ }
+ return 0;
}
+
D power/boot.c => power/boot.c +0 -477
@@ 1,477 0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-
-#define DEFSYS "cyc!bootes"
-#define DEFFILE "/mips/9"
-
-Fcall hdr;
-char *scmd;
-
-char buf[4*1024];
-char bootfile[5*NAMELEN];
-char sys[NAMELEN];
-
-int printcol; /* so we can use the kernel's small print */
-
-int fd;
-int cfd;
-int efd;
-int setkey;
-
-/*
- * predeclared
- */
-int outin(char *, char *, int);
-void prerror(char *);
-void error(char *);
-void boot(int);
-int dkdial(char *);
-int bitdial(char *);
-int preamble(int);
-void srvcreate(char*, int);
-void settime(void);
-void key(void);
-int passwd(char*, int);
-int passtokey(char*, char*, int);
-
-/*
- * usage: 9b [-mp] [server] [file]
- *
- * default server is `bitbootes', default file is `/mips/9'
- */
-void
-main(int argc, char *argv[])
-{
- int i;
- int manual=0;
-
- open("#c/cons", OREAD);
- open("#c/cons", OWRITE);
- open("#c/cons", OWRITE);
-
- argv++;
- argc--;
-
- while(argc > 0){
- if(argv[0][0] == '-'){
- if(argv[0][1] == 'm')
- manual = 1;
- else if(argv[0][1] == 'k')
- setkey = 1;
- argc--;
- argv++;
- } else
- break;
- }
-
- strcpy(sys, DEFSYS);
- strcpy(bootfile, DEFFILE);
- switch(argc){
- case 1:
- strcpy(bootfile, argv[0]);
- break;
- case 2:
- strcpy(bootfile, argv[0]);
- strcpy(sys, argv[1]);
- break;
- }
-
- key();
- boot(manual);
- for(;;){
- if(fd > 0)
- close(fd);
- if(cfd > 0)
- close(cfd);
- fd = cfd = 0;
- boot(1);
- }
-}
-
-int
-bitdial(char *arg)
-{
- USED(arg);
- return open("#3/bit3", ORDWR);
-}
-
-int
-dkdial(char *arg)
-{
- int fd;
- char cmd[64];
- static int mounted;
-
- if(!mounted){
- /*
- * grab the hsvme and configure it for a datakit
- */
- efd = open("#h/ctl", ORDWR);
- if(efd < 0){
- prerror("opening #h/ctl");
- return -1;
- }
- if(write(efd, "push dkmux", sizeof("push dkmux")-1)<0){
- close(efd);
- prerror("push dkmux");
- return -1;
- }
- if(write(efd, "config 4 256 restart dk", sizeof("config 4 256 restart dk")-1)<0){
- close(efd);
- prerror("config 4 256 restart dk");
- return -1;
- }
- mounted = 1;
- sleep(2000); /* wait for things to settle down */
- }
-
- /*
- * grab a datakit channel and call up the file server
- */
- fd = open("#k/dk/5/data", ORDWR);
- if(fd < 0) {
- prerror("opening #k/dk/5/data");
- return -1;
- }
- cfd = open("#k/dk/5/ctl", ORDWR);
- if(cfd < 0){
- close(fd);
- prerror("opening #k/dk/5/ctl");
- return -1;
- }
- sprint(cmd, "connect %s", arg);
- if(write(cfd, cmd, strlen(cmd))<0){
- close(cfd);
- close(fd);
- prerror(cmd);
- return -1;
- }
- return fd;
-}
-
-int
-hotdial(char *arg)
-{
- USED(arg);
- return open("#H/hotrod", ORDWR);
-}
-
-int
-preamble(int fd)
-{
- int n;
-
- print("nop...");
- hdr.type = Tnop;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n){
- print("n = %d\n", n);
- prerror("write nop");
- return 0;
- }
- reread:
- n = read(fd, buf, sizeof buf);
- if(n <= 0){
- prerror("read nop");
- return 0;
- }
- if(n == 2)
- goto reread;
- if(convM2S(buf, &hdr, n) == 0) {
- print("n = %d; buf = %.2x %.2x %.2x %.2x\n",
- n, buf[0], buf[1], buf[2], buf[3]);
- prerror("format nop");
- return 0;
- }
- if(hdr.type != Rnop){
- prerror("not Rnop");
- return 0;
- }
- if(hdr.tag != NOTAG){
- prerror("tag not NOTAG");
- return 0;
- }
-
- print("session...");
- hdr.type = Tsession;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n){
- prerror("write session");
- return 0;
- }
- n = read(fd, buf, sizeof buf);
- if(n <= 0){
- prerror("read session");
- return 0;
- }
- if(convM2S(buf, &hdr, n) == 0){
- prerror("format session");
- return 0;
- }
- if(hdr.tag != NOTAG){
- prerror("tag not NOTAG");
- return 0;
- }
- if(hdr.type == Rerror){
- fprint(2, "boot: error %s\n", hdr.ename);
- return 0;
- }
- if(hdr.type != Rsession){
- prerror("not Rsession");
- return 0;
- }
- return 1;
-}
-
-void
-boot(int ask)
-{
- int n, f, tries;
-
- if(ask)
- outin("server", sys, sizeof(sys));
-
- for(tries = 0; tries < 5; tries++){
- fd = -1;
- if(strncmp(sys, "bit!", 4) == 0)
- fd = bitdial(&sys[4]);
- else if(strncmp(sys, "cyc!", 4) == 0)
- fd = hotdial(&sys[4]);
- else if(strncmp(sys, "dk!", 3) == 0)
- fd = dkdial(&sys[3]);
- if(fd >= 0)
- break;
- print("can't connect, retrying...\n");
- sleep(1000);
- }
- if(fd < 0){
- print("can't connect\n");
- return;
- }
-
- if(!preamble(fd))
- return;
-
- srvcreate("boot", fd);
- srvcreate("bootes", fd);
-
- print("mount...");
- if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
- error("mount");
-
- settime();
-
- print("success\n");
-
- if(ask){
- execl("/mips/init", "init", "-mc", 0);
- } else {
- execl("/mips/init", "init", "-c", 0);
- }
- error("/mips/init");
-}
-
-/*
- * print error
- */
-void
-prerror(char *s)
-{
- char buf[64];
-
- errstr(buf);
- fprint(2, "boot: %s: %s\n", s, buf);
-}
-
-/*
- * print error and exit
- */
-void
-error(char *s)
-{
- char buf[64];
-
- errstr(buf);
- fprint(2, "boot: %s: %s\n", s, buf);
- exits(0);
-}
-
-/*
- * prompt and get input
- */
-int
-outin(char *prompt, char *def, int len)
-{
- int n;
- char buf[256];
-
- do{
- print("%s[%s]: ", prompt, def);
- n = read(0, buf, len);
- }while(n==0);
- if(n < 0)
- error("can't read #c/cons; please reboot");
- if(n != 1){
- buf[n-1] = 0;
- strcpy(def, buf);
- }
- return n;
-}
-
-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)
- error("create");
- sprint(buf, "%d", fd);
- if(write(f, buf, strlen(buf)) != strlen(buf))
- error("write");
- close(f);
-}
-
-void
-settime(void)
-{
- char dirbuf[DIRLEN];
- Dir dir;
- int f;
-
- print("time...");
- /*
- * set the time from the access time of the root
- * of the file server
- */
- 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)
- error("stat");
- convM2D(dirbuf, &dir);
- sprint(dirbuf, "%ld", dir.atime);
- unmount(0, "/n/boot");
- f = open("#c/time", OWRITE);
- write(f, dirbuf, strlen(dirbuf));
- close(f);
-}
-
-void
-key(void)
-{
- char password[20], key[7];
- int prompt, fd;
-
- prompt = setkey;
- fd = open("#r/nvram", ORDWR);
- if(fd < 0){
- prompt = 1;
- prerror("can't open nvram");
- }
- if(prompt){
- do
- if(passwd(password, sizeof password) < 0){
- prerror("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);
- prerror("can't read key from nvram");
- }
- if(setkey && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){
- close(fd);
- prerror("can't write key to nvram");
- }
- close(fd);
- fd = open("#c/key", OWRITE);
- if(fd < 0)
- prerror("can't open key");
- else if(write(fd, key, 7) != 7)
- prerror("can't write key");
- close(fd);
-}
-
-int
-passwd(char *p, int len)
-{
- char c;
- int i, n, fd;
-
- fd = open("#c/consctl", OWRITE);
- if(fd < 0)
- return -1;
- write(fd, "rawon", 5);
- Prompt:
- print("password: ");
- n = 0;
- for(;;){
- do{
- i = read(0, &c, 1);
- if(i < 0){
- close(fd);
- return -1;
- }
- }while(i == 0);
- switch(c){
- case '\n':
- p[n] = '\0';
- close(fd);
- print("\n");
- return 0;
- 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;
- }
- }
-}
-
-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;
-}
M power/l.s => power/l.s +1 -1
@@ 151,7 151,7 @@ TEXT gotolabel(SB), $-4
TEXT getcallerpc(SB), $0
- MOVW 4(SP), R1
+ MOVW 0(SP), R1
RET
TEXT gotopc(SB), $8
M power/trap.c => power/trap.c +7 -2
@@ 340,8 340,11 @@ dumpstack(void)
if(u)
for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){
v = *(ulong*)l;
- if(KTZERO < v && v < (ulong)&etext)
+ if(KTZERO < v && v < (ulong)&etext){
print("%lux=%lux\n", l, v);
+ prflush();
+ delay(250);
+ }
}
}
@@ 357,8 360,10 @@ dumpregs(Ureg *ur)
else
print("registers for kernel\n");
l = &ur->status;
- for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
+ for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2){
print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
+ prflush();
+ }
}
/*