Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/ss/boot.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname ss/boot.c 1990/1223
## diff -e /dev/null /n/bootesdump/1990/1223/sys/src/9/sparc/boot.c
0a
#include <u.h>
#include <libc.h>
#include <fcall.h>

Fcall	hdr;
char	buf[100];
char	bootline[64];
char	bootdevice;
char	bootserver[64];

void	error(char*);
void	sendmsg(int, char*);

main(int argc, char *argv[])
{
	int cfd, fd, n, fu, f, i;
	char buf[256];
	int p[2];

	open("#c/cons", OREAD);
	open("#c/cons", OWRITE);
	open("#c/cons", OWRITE);

	fd = open("#e/bootline", OREAD);
	if(fd >= 0){
		read(fd, bootline, sizeof bootline);
		close(fd);
	}
	fd = open("#e/bootdevice", OREAD);
	if(fd >= 0){
		read(fd, &bootdevice, 1);
		close(fd);
	}
	fd = open("#e/bootserver", OREAD);
	if(fd >= 0){
		read(fd, bootserver, 64);
		close(fd);
	} else
		strcpy(bootserver, "nfs");

	switch(bootdevice){
	case 'A':
		/*
		 *  grab the rs232 line,
		 *  make it 9600 baud,
		 *  push the async protocol onto it,
		 */
		cfd = open("#c/rs232ctl", 2);
		if(cfd < 0)
			error("opening #c/rs232ctl");
		sendmsg(cfd, "B9600");
		sendmsg(cfd, "push async");
		break;
	case 'a':
		/*
		 *  grab the rs232 line,
		 *  make it 19200 baud,
		 *  push the async protocol onto it,
		 */
		cfd = open("#c/rs232ctl", 2);
		if(cfd < 0)
			error("opening #c/rs232ctl");
		sendmsg(cfd, "B19200");
		sendmsg(cfd, "push async");
		break;
	default:
		/*
		 *  grab the incon,
		 */
		cfd = open("#i/ctl", 2);
		if(cfd < 0)
			error("opening #i/ctl");
		break;
	}

	/*
	 *  push the dk multiplexor onto the communications link,
	 *  and use line 1 as the signalling channel.
	 */
	sendmsg(cfd, "push dkmux");
	sendmsg(cfd, "config 1 16 norestart");

	/*
	 *  fork a process to hold the device channel open
	 */
	switch(fork()){
	case -1:
		break;
	case 0:
		for(;;)
			sleep(60*1000);
		exit(0);
	default:
		close(cfd);
		break;
	}

	/*
	 *  open a datakit channel and call ken, leave the
	 *  incon ctl channel open
	 */
	for(i = 0; ; i++){
		fd = open("#k/2/data", 2);
		if(fd < 0)
			error("opening #k/2/data");
		cfd = open("#k/2/ctl", 2);
		if(cfd < 0)
			error("opening #k/2/ctl");
		sprint(buf, "connect %s", bootserver);
		n = strlen(buf);
		if(write(cfd, buf, n) == n)
			break;
		if(i == 5)
			error("dialing");
		print("error dialing, retrying ...\n");
		close(fd);
		close(cfd);
	}
	print("connected to %s\n", bootserver);
	close(cfd);

	/*
	 *  talk to the file server
	 */
	print("nop...");
	hdr.type = Tnop;
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("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)
		error("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]);
		error("format nop");
	}
	if(hdr.type != Rnop)
		error("not Rnop");

	print("session...");
	hdr.type = Tsession;
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("write session");
	n = read(fd, buf, sizeof buf);
	if(n <= 0)
		error("read session");
	if(convM2S(buf, &hdr, n) == 0)
		error("format session");
	if(hdr.type == Rerror){
		print("error %s;", hdr.ename);
		error(hdr.ename);
	}
	if(hdr.type != Rsession)
		error("not Rsession");

	print("post...");
	sprint(buf, "#s/%s", "bootes");
	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);
	sprint(buf, "#s/%s", "bootes");
	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);
	
	print("mount...");
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");
	print("success\n");
	if(strchr(bootline, ' '))
		execl("/68020/init", "init", "-m", 0);
	else
		execl("/68020/init", "init", 0);
	error("/68020/init");
}

void
sendmsg(int fd, char *msg)
{
	int n;

	n = strlen(msg);
	if(write(fd, msg, n) != n)
		error(msg);
}

void
error(char *s)
{
	char buf[64];

	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
	exits(0);
}
.
## diffname ss/boot.c 1990/1226
## diff -e /n/bootesdump/1990/1223/sys/src/9/sparc/boot.c /n/bootesdump/1990/1226/sys/src/9/sparc/boot.c
189,190c
		execl("/sparc/init", "init", 0);
	error("/sparc/init");
.
187c
		execl("/sparc/init", "init", "-m", 0);
.
22a
write(1, "hello from boot\n", 16);
bind("#c", "/dev", MREPL);
binit(0, 0);
bitblt(&screen, Pt(100, 100), &screen, Rect(100, 100, 300, 200), 0xF);
.
2a
#include <libg.h>
.
## diffname ss/boot.c 1990/1227
## diff -e /n/bootesdump/1990/1226/sys/src/9/sparc/boot.c /n/bootesdump/1990/1227/sys/src/9/sparc/boot.c
27a
else
bitblt(&screen, Pt(500, 500), &screen, Rect(100, 100, 300, 200), 0xF);

.
26a
if(fork()==0)
.
## diffname ss/boot.c 1990/1231
## diff -e /n/bootesdump/1990/1227/sys/src/9/sparc/boot.c /n/bootesdump/1990/1231/sys/src/9/sparc/boot.c
219a
}

/*
 *  prompt and get input
 */
int
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;
.
211a
/*
 *  print error and exit
 */
.
207,209c
	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
.
205c
	char buf[64];
.
203c
prerror(char *s)
.
201a
/*
 *  print error
 */
.
198,199c
		execl("/mips/init", "init", 0);
	error("/mips/init");
.
195,196c
	close(fd);

	if(ask)
		execl("/mips/init", "init", "-m", 0);
.
188c

.
180d
172c
	sprint(buf, "#s/%s", srvname);
.
168,169c
	if(hdr.type != Rsession){
		prerror("not Rsession");
		return;
	}
.
165,166c
		fprint(2, "boot: error %s\n", hdr.ename);
		return;
.
160,163c
	if(n <= 0){
		prerror("read session");
		return;
	}
	if(convM2S(buf, &hdr, n) == 0){
		prerror("format session");
		return;
	}
	if(hdr.tag != ~0){
		prerror("tag not ~0");
		return;
	}
.
157,158c
	if(write(fd, buf, n) != n){
		prerror("write session");
		return;
	}
.
150,151c
	if(hdr.type != Rnop){
		prerror("not Rnop");
		return;
	}
	if(hdr.tag != ~0){
		prerror("tag not ~0");
		return;
	}
.
148c
		prerror("format nop");
		return;
.
141,144c
	if(n <= 0){
		prerror("read nop");
		return;
	}
	if(n == 2)
		goto reread;
.
138,139c
	if(write(fd, buf, n) != n){
		print("n = %d\n", n);
		prerror("write nop");
		return;
	}
  reread:
.
131,133c
void
boot(int ask)
{
	int n, f, tries;
	char *srvname;

	if(ask){
		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;
	}

.
128,129c
	return fd;
}
.
126a
		close(fd);
		cfd = fd = -1;
		prerror(cmd);
		return -1;
.
125a
		fd = -1;
		prerror("opening #kdk/5/ctl");
		return -1;
	}
	sprint(cmd, "connect %s", arg);
	if(write(cfd, cmd, strlen(cmd))<0){
.
111,124c
	fd = open("#kdk/5/data", 2);
	if(fd < 0) {
		prerror("opening #kdk/5/data");
		return -1;
	}
	cfd = open("#kdk/5/ctl", 2);
	if(cfd < 0){
.
108,109c
	 *  grab a datakit channel and call up the file server
.
106a
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 */
	}

.
105a
	return fd;
}
.
104c
		close(fd);
		fd = cfd = -1;
		prerror(a->cmd);
		return -1;
.
89,102c
	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){
.
86,87c
	 *  grab a nonet channel and call up the file server
.
79,82c
		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;
.
77c
		 *  grab a lance channel, make it recognize ether type 0x900,
		 *  and push the nonet ethernet multiplexor onto it.
.
75c
	}

	boot(manual);
	for(;;){
		if(fd > 0)
			close(fd);
		if(cfd > 0)
			close(cfd);
		fd = cfd = 0;
		boot(1);
	}
}

int
bitdial(char *arg)
{
	return open("#3/bit3", ORDWR);
}

int
nonetdial(char *arg)
{
	int efd, cfd, fd;
	Address *a;
	static int mounted;

	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;
	}

	if(!mounted){
.
63,73c
	case 2:
		strcpy(bootfile, argv[0]);
		strcpy(sys, argv[1]);
.
50,61c
	strcpy(sys, DEFSYS);
	strcpy(bootfile, DEFFILE);
	switch(argc){
	case 1:
		strcpy(bootfile, argv[0]);
.
38,48d
33,36c
	argv++;
	argc--;	

	while(argc > 0){
		if(argv[0][0] == '-'){
			if(argv[0][1] == 'm')
				manual = 1;
			argc--;
			argv++;
		} else
			break;
.
31a
	i = create("#e/sysname", 1, 0666);
	if(i < 0)
		error("sysname");
	if(write(i, argv[0], strlen(argv[0])) != strlen(argv[0]))
		error("sysname");
	close(i);
.
21,30c
	open("#c/cons", 0);
	open("#c/cons", 1);
	open("#c/cons", 1);
.
17,19c
	int i;
	int manual=0;
	char buf[128];
.
14a
int fd;
int cfd;
int efd;

typedef
struct address {
	char *name;
	char *cmd;
} Address;

Address addr[] = {
	{ "ross", "connect 020701005eff" },
	{ "bootes", "connect 080069020205" },
	{ "helix", "connect 080069020427" },
	{ "spindle", "connect 0800690202df" },
	{ "r70", "connect 08002b04265d" },
	{ 0 }
};

/*
 *  predeclared
 */
int	outin(char *, char *, int);
void	prerror(char *);
void	error(char *);
void	boot(int);
int	dkdial(char *);
int	nonetdial(char *);
int	bitdial(char *);

/*
 *  usage: 9b [-a] [server] [file]
 *
 *  default server is `bootes', default file is `/mips/9'
 */
.
12,13c
char	buf[4*1024];
char	bootfile[5*NAMELEN];
char	sys[NAMELEN];
.
7,10c
char	*scmd;
.
5a
#define DEFSYS "bootes"
#define DEFFILE "/mips/9"

.
3d
## diffname ss/boot.c 1991/0109
## diff -e /n/bootesdump/1990/1231/sys/src/9/sparc/boot.c /n/bootesdump/1991/0109/sys/src/9/sparc/boot.c
386d
354,355c
		execl("/sparc/init", "init", "-t", 0);
	error("/sparc/init");
.
352c
		execl("/sparc/init", "init", "-t", "-m", 0);
.
350a
	if(net){
		char buf[128];

		fd = create("#e/bootnet", 1, 0666);
		if(fd >= 0){
			if(write(fd, net, strlen(net)) != strlen(net))
				error("writing bootnet");
			close(fd);
			sprint(buf, "/net/%s", net);
			if(bind(netdev, buf, MREPL) < 0)
				error("binding bootnet");
		}
	}

.
230a
	net = "dk";
	netdev = "#kdk";
.
174a

	net = "nonet";
	netdev = "#nnonet";
.
87d
83,85d
81d
69a
	manual = 1;
.
68c
	argc--;
.
66a
	for(i = 0; i < argc; i++)
		print("argv[%d] = %s\n", i, argv[i]);

.
59a
	strcpy(buf, "none");
	outin("user", buf, sizeof(buf));
	i = open("#c/user", 2);
	if(i >= 0){
		write(i, buf, strlen(buf));
		close(i);
	}
.
48c
 *  default server is `bootes', default file is `/sparc/9'
.
12d
7a
char	*net;
char	*netdev;

.
6d
## diffname ss/boot.c 1991/0112
## diff -e /n/bootesdump/1991/0109/sys/src/9/sparc/boot.c /n/bootesdump/1991/0112/sys/src/9/sparc/boot.c
81d
## diffname ss/boot.c 1991/01151
## diff -e /n/bootesdump/1991/0112/sys/src/9/sparc/boot.c /n/bootesdump/1991/01151/sys/src/9/sparc/boot.c
360d
358a

	/*
	 * set the time from the access time of the root of the file server,
	 * accessible as /..
	 */
	print("time...");
	if(stat("/..", dirbuf) < 0)
		error("stat");
	convM2D(dirbuf, &dir);
	f = open("#c/time", OWRITE);
	sprint(dirbuf, "%ld", dir.atime);
	write(f, dirbuf, strlen(dirbuf));
	close(f);
	
.
249a
	Dir dir;
	char dirbuf[DIRLEN];
.
## diffname ss/boot.c 1991/0131
## diff -e /n/bootesdump/1991/01151/sys/src/9/sparc/boot.c /n/bootesdump/1991/0131/sys/src/9/sparc/boot.c
378,388c
		char buf[64];
		sprint(buf, "/lib/netaddr.%s", net);
		print("binding %s onto /lib/netaddr.net\n", buf);
		bind(buf, "/lib/netaddr.net", MREPL);
.
376a
	if(netdev){
		char buf[64];
		sprint(buf, "/net/%s", net);
		bind(netdev, buf, MREPL);
		bind(netdev, "/net/net", MREPL);
	}
.
## diffname ss/boot.c 1991/0201 # deleted
## diff -e /n/bootesdump/1991/0131/sys/src/9/sparc/boot.c /n/bootesdump/1991/0201/sys/src/9/sparc/boot.c
1,442d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].