⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 astarld.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>enum{	Doff=		4,	/* offset into Cpline.bytes of data */	Memsize=	1<<16,	/* max size of 186 memory */};int dump, image, noload, nostart;typedef struct{	int	type;	int	dlen;	ulong	addr;	uchar	bytes[256+4];	uchar	csum;} Cpline;char*	rdcpline(Biobuf*, Cpline*);void	clearmem(int);voidusage(void){	fprint(2, "usage: %s [-0123] file\n", argv0);	exits("usage");}static voidloadimage(char* file, int mfd){	uchar buf[256];	int fd, n, r;	if((fd = open(file, OREAD)) < 0)		sysfatal("opening %s: %r", file);	seek(mfd, 0, 0);	do{		n = read(fd, buf, sizeof(buf));		if(n < 0)			sysfatal("read %s: %r", file);		if(n > 0)			if((r = write(mfd, buf, n)) != n)				sysfatal("write %s: %d != %d: %r", file, n, r);	}while(n > 0);	close(fd);}static voidloadhex(char* file, int mfd){	int done;	Cpline c;	Biobuf *b;	char *err;	ulong addr, seg;	int lineno;	uchar buf[1024];	b = Bopen(file, OREAD);	if(b == 0)		sysfatal("opening %s: %r", file);	lineno = 1;	seg = 0;	for(done = 0; !done; lineno++){		err = rdcpline(b, &c);		if(err)			sysfatal("%s line %d: %s", file, lineno, err);		switch(c.type){		case 0: /* data */			addr = seg + c.addr;			if(addr + c.dlen > Memsize)				sysfatal("addr out of range: %lux-%lux", addr, addr+c.dlen);			if(seek(mfd, addr, 0) < 0)				sysfatal("seeking to %lud: %r", addr);			if(write(mfd, c.bytes+Doff, c.dlen) != c.dlen)				sysfatal("writing: %r");			if(seek(mfd, addr, 0) < 0)				sysfatal("seeking to %lud: %r", addr);			if(read(mfd, buf, c.dlen) != c.dlen)				sysfatal("reading: %r");			if(memcmp(buf, c.bytes+Doff, c.dlen) != 0)				print("readback error at %lux\n", addr);			if(dump)				print("%8.8lux: %d\n", addr, c.dlen);			break;		case 1: /* termination */			done = 1;			break;		case 2: /* segment */			seg = ((c.bytes[Doff]<<8) | c.bytes[Doff+1]) <<4;			if(seg >= Memsize)				sysfatal("seg out of range: %lux", seg);			if(dump)				print("seg %8.8lux\n", seg);			break;		default: /* ignore */			if(dump)				print("bad type %d\n", c.type);			break;		}	}	Bterm(b);}voidmain(int argc, char **argv){	int unit;	int cfd, mfd;	char file[128];	unit = 0;	ARGBEGIN{	case 'd':		dump = 1;		break;	case 'i':		image = 1;		break;	case 'n':		noload = 1;		break;	case 's':		nostart = 1;		break;	case '0':		unit = 0;		break;	case '1':		unit = 1;		break;	case '2':		unit = 2;		break;	case '3':		unit = 3;		break;	}ARGEND;	if(argc == 0)		usage();	if(noload == 0){		sprint(file, "#G/astar%dctl", unit);		cfd = open(file, ORDWR);		if(cfd < 0)			sysfatal("opening %s\n", file);		sprint(file, "#G/astar%dmem", unit);		mfd = open(file, ORDWR);		if(mfd < 0)			sysfatal("opening %s\n", file);			if(write(cfd, "download", 8) != 8)			sysfatal("requesting download: %r");	} else {		cfd = -1;		mfd = create("/tmp/astarmem", ORDWR, 0664);		if(mfd < 0)			sysfatal("creating /tmp/astarmem: %r");	}	if(image)		loadimage(argv[0], mfd);	else{		/* zero out the memory */		clearmem(mfd);		loadhex(argv[0], mfd);	}	close(mfd);	if(noload == 0 && nostart == 0)		if(write(cfd, "run", 3) != 3)			sysfatal("requesting run: %r");	close(cfd);	exits(0);}voidclearmem(int fd){	char buf[4096];	char buf2[4096];	int i, n;	memset(buf, 0, sizeof buf);	for(i = 0; i < Memsize; i += n){		if(seek(fd, i, 0) < 0)			sysfatal("seeking to %ux: %r", i);		n = write(fd, buf, sizeof buf);		if(n <= 0)			break;		if(seek(fd, i, 0) < 0)			sysfatal("seeking to %ux: %r", i);		n = read(fd, buf2, sizeof buf2);		if(n <= 0)			break;		if(memcmp(buf, buf2, sizeof buf) != 0)			print("error zeroing mem at %ux\n", i);	}	print("zero'd %d bytes\n", i);}inthex(char c){	if(c <= '9' && c >= '0')		return c - '0';	if(c <= 'f' && c >= 'a')		return (c - 'a') + 10;	if(c <= 'F' && c >= 'A')		return (c - 'A') + 10;	return -1;}char*rdcpline(Biobuf *b, Cpline *cpl){	char *cp, *ep, *p;	uchar *up;	uchar csum;	int c;	cp = Brdline(b, '\n');	if(cp == 0)		return "early eof";	ep = cp + Blinelen(b);	if(*cp++ != ':')		return "bad load line";	csum = 0;	up = cpl->bytes; 	for(p = cp; p < ep;){		c = hex(*p++)<<4;		c |= hex(*p++);		if(c < 0)			break;		csum += c;		*up++ = c;	}	cpl->csum = csum;	if(csum != 0){		fprint(2, "checksum %ux\n", csum);		return "bad checksum";	}	cpl->dlen = cpl->bytes[0];	if(cpl->dlen + 5 != up - cpl->bytes){		fprint(2, "%d %ld\n", cpl->dlen + 5, up - cpl->bytes);		return "bad data length";	}	cpl->addr = (cpl->bytes[1]<<8) | cpl->bytes[2];	cpl->type = cpl->bytes[3];	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -