plan 9 kernel history: overview | file list | diff list

1990/0721/power/boot.c (diff list | history)

1990/0721/sys/src/9/power/boot.c:1,3231990/0722/sys/src/9/power/boot.c:1,323 (short | long | prev | next)
1990/0227    
#include <u.h> 
#include <libc.h> 
 
#include <fcall.h> 
 
1990/0427    
#define DEFSYS "bitbootes" 
#define DEFFILE "/mips/9" 
 
1990/0227    
Fcall	hdr; 
1990/0427    
char	*sys; 
char	*scmd; 
char	*bootfile; 
1990/0227    
 
1990/0427    
char	sbuf[2*NAMELEN]; 
char	buf[4*1024]; 
1990/0227    
 
1990/0427    
int fd; 
int cfd; 
int efd; 
 
1990/0227    
typedef 
struct address { 
	char *name; 
	char *cmd; 
1990/0721    
	char *srvname; 
1990/0227    
} Address; 
 
Address addr[] = { 
1990/0721    
	{ "bitbootes", "bitconnect", "bit!bootes" }, 
	{ "ross", "connect 020701005eff", "nonet!ross" }, 
	{ "bootes", "connect 080069020205", "nonet!bootes" }, 
	{ "helix", "connect 080069020427", "nonet!helix" }, 
	{ "spindle", "connect 0800690202df", "nonet!spindle" }, 
	{ "r70", "connect 08002b04265d", "nonet!r70" }, 
1990/0227    
	{ 0 } 
}; 
 
1990/0427    
/* 
 *  predeclared 
 */ 
1990/0721    
Address* lookup(char *); 
1990/0427    
int	outin(char *, char *, char *, int); 
void	prerror(char *); 
void	error(char *); 
void	boot(int); 
1990/0227    
 
1990/0427    
/* 
 *  usage: 9b [-a] [server] [file] 
 * 
1990/0504    
 *  default server is `bitbootes', default file is `/mips/9' 
1990/0427    
 */ 
main(int argc, char *argv[]) 
1990/0227    
{ 
1990/0427    
	int i; 
	int manual=0; 
1990/0227    
 
1990/0427    
	open("#c/cons", 0); 
	open("#c/cons", 1); 
	open("#c/cons", 1); 
 
1990/0504    
	i = create("#e/sysname", 1, 0666); 
	if(i < 0) 
		error("sysname"); 
	if(write(i, argv[0], strlen(argv[0])) <= 0) 
		error("sysname"); 
	close(i); 
1990/0427    
 
	argv++; 
	argc--;	 
 
	while(argc > 0){ 
		if(argv[0][0] == '-'){ 
			if(argv[0][1] == 'm') 
				manual = 1; 
			argc--; 
			argv++; 
		} else 
			break; 
1990/0227    
	} 
1990/0427    
 
	sys = DEFSYS; 
	bootfile = DEFFILE; 
	switch(argc){ 
	case 1: 
		bootfile = argv[0]; 
		break; 
	case 2: 
		bootfile = argv[0]; 
		sys = argv[1]; 
		break; 
1990/0227    
	} 
1990/0427    
 
	boot(manual); 
	for(;;){ 
		if(fd > 0) 
			close(fd); 
		if(cfd > 0) 
			close(cfd); 
		if(efd > 0) 
			close(efd); 
		fd = cfd = efd = 0; 
		boot(1); 
	} 
1990/0227    
} 
 
1990/0427    
void 
boot(int ask) 
1990/0227    
{ 
1990/0427    
	int n, f; 
1990/0721    
	Address *a; 
1990/0227    
 
1990/0721    
	if(ask){ 
1990/0427    
		outin("server", sys, sbuf, sizeof(sbuf)); 
		sys = sbuf; 
	} 
1990/0721    
	a = lookup(sys); 
	if(a == 0){ 
1990/0427    
		fprint(2, "boot: %s unknown\n", sys); 
		return; 
	} 
1990/0721    
	scmd = a->cmd; 
1990/0227    
 
	/* 
1990/0427    
	 *  for the bit, we skip all the ether goo 
1990/0227    
	 */ 
	if(strcmp(scmd, "bitconnect") == 0){ 
1990/0324    
		fd = open("#3/bit3", ORDWR); 
1990/0427    
		if(fd < 0){ 
			prerror("opening #3/bit3"); 
			return; 
		} 
1990/0227    
		goto Mesg; 
	} 
 
	/* 
	 *  grab a lance channel, make it recognize ether type 0x900, 
	 *  and push the nonet ethernet multiplexor onto it. 
	 */ 
1990/0427    
	efd = open("#l/1/ctl", 2); 
	if(efd < 0){ 
		prerror("opening #l/1/ctl"); 
		return; 
	} 
	if(write(efd, "connect 0x900", sizeof("connect 0x900")-1)<0){ 
		prerror("connect 0x900"); 
		return; 
	} 
	if(write(efd, "push noether", sizeof("push noether")-1)<0){ 
		prerror("push noether"); 
		return; 
	} 
1990/0721    
	if(write(efd, "config nonet", sizeof("config nonet")-1)<0){ 
		prerror("config nonet"); 
		return; 
	} 
1990/0227    
 
	/* 
	 *  grab a nonet channel and call up the ross file server 
	 */ 
1990/0721    
	fd = open("#nnonet/2/data", 2); 
1990/0427    
	if(fd < 0) { 
1990/0704    
		prerror("opening #n/2/data"); 
1990/0722    
		prerror("opening #nnonet/2/data"); 
1990/0427    
		return; 
	} 
1990/0721    
	cfd = open("#nnonet/2/ctl", 2); 
1990/0427    
	if(cfd < 0){ 
1990/0704    
		prerror("opening #n/2/ctl"); 
1990/0722    
		prerror("opening #nnonet/2/ctl"); 
1990/0427    
		return; 
	} 
	if(write(cfd, scmd, strlen(scmd))<0){ 
		prerror(scmd); 
		return; 
	} 
1990/0227    
 
    Mesg: 
	print("nop..."); 
	hdr.type = Tnop; 
	n = convS2M(&hdr, buf); 
1990/0427    
	if(write(fd, buf, n) != n){ 
		print("n = %d\n", n); 
		prerror("write nop"); 
		return; 
	} 
1990/0227    
	n = read(fd, buf, sizeof buf); 
1990/0427    
	if(n <= 0){ 
		prerror("read nop"); 
		return; 
	} 
1990/0227    
	if(convM2S(buf, &hdr, n) == 0) { 
		print("n = %d; buf = %.2x %.2x %.2x %.2x\n", 
			n, buf[0], buf[1], buf[2], buf[3]); 
1990/0427    
		prerror("format nop"); 
		return; 
1990/0227    
	} 
1990/0427    
	if(hdr.type != Rnop){ 
		prerror("not Rnop"); 
		return; 
	} 
1990/0227    
 
	print("session..."); 
	hdr.type = Tsession; 
	hdr.lang = 'v'; 
	n = convS2M(&hdr, buf); 
1990/0427    
	if(write(fd, buf, n) != n){ 
		prerror("write session"); 
		return; 
	} 
1990/0227    
	n = read(fd, buf, sizeof buf); 
1990/0427    
	if(n <= 0){ 
		prerror("read session"); 
		return; 
	} 
	if(convM2S(buf, &hdr, n) == 0){ 
		prerror("format session"); 
		return; 
	} 
	if(hdr.type != Rsession){ 
		prerror("not Rsession"); 
		return; 
	} 
1990/0227    
	if(hdr.err){ 
		print("error %d;", hdr.err); 
1990/0427    
		prerror("remote error"); 
		return; 
1990/0227    
	} 
 
	print("post..."); 
1990/0721    
	sprint(buf, "#s/%s", a->srvname); 
1990/0227    
	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); 
	f = create("#s/boot", 1, 0666); 
	if(f < 0) 
		error("create"); 
	sprint(buf, "%d", fd); 
	if(write(f, buf, strlen(buf)) != strlen(buf)) 
		error("write"); 
	close(f); 
1990/0427    
 
1990/0227    
	print("mount..."); 
	if(bind("/", "/", MREPL) < 0) 
		error("bind"); 
	if(mount(fd, "/", MAFTER|MCREATE, "") < 0) 
		error("mount"); 
	print("success\n"); 
1990/0504    
	close(fd); 
 
	if(ask) 
		execl("/mips/init", "init", "-m", 0); 
1990/06111    
	else 
		execl("/mips/init", "init", 0); 
1990/0227    
	error("/mips/init"); 
} 
 
1990/0427    
/* 
 *  print error 
 */ 
1990/0227    
void 
1990/0427    
prerror(char *s) 
{ 
	char buf[64]; 
 
	errstr(0, buf); 
	fprint(2, "boot: %s: %s\n", s, buf); 
} 
 
/* 
 *  print error and exit 
 */ 
void 
1990/0227    
error(char *s) 
{ 
	char buf[64]; 
 
	errstr(0, buf); 
	fprint(2, "boot: %s: %s\n", s, buf); 
	exits(0); 
1990/0427    
} 
 
/* 
 *  lookup the address for a system 
 */ 
1990/0721    
Address * 
1990/0427    
lookup(char *arg) 
{ 
	Address *a; 
 
	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) 
1990/0721    
			return a; 
1990/0427    
	} 
	return 0; 
} 
 
/* 
 *  prompt and get input 
 */ 
int 
outin(char *prompt, char *def, char *buf, int len) 
{ 
	int n; 
 
	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) 
		strcpy(buf, def); 
	else 
		buf[n-1] = 0; 
	return n; 
1990/0227    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)