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

📄 pc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"all.h"#include	"mem.h"#include	"io.h"#include	"ureg.h"/* * Where configuration info is left for the loaded programme. * This will turn into a structure as more is done by the boot loader * (e.g. why parse the .ini file twice?). * There are 1024 bytes available at CONFADDR. */#define BOOTLINE	((char*)CONFADDR)#define BOOTLINELEN	64#define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN))#define	BOOTARGSLEN	(1024-BOOTLINELEN)#define	MAXCONF		32#define KADDR(a)	((void*)((ulong)(a)|KZERO))char bootdisk[NAMELEN];char *confname[MAXCONF];char *confval[MAXCONF];int nconf;static int isoldbcom;intgetcfields(char* lp, char** fields, int n, char* sep){	int i;	for(i = 0; lp && *lp && i < n; i++){		while(*lp && strchr(sep, *lp) != 0)			*lp++ = 0;		if(*lp == 0)			break;		fields[i] = lp;		while(*lp && strchr(sep, *lp) == 0){			if(*lp == '\\' && *(lp+1) == '\n')				*lp++ = ' ';			lp++;		}	}	return i;}static voidoptions(void){	uchar *bda;	long i, n;	char *cp, *line[MAXCONF], *p, *q;	if(strncmp(BOOTARGS, "ZORT 0\r\n", 8)){		isoldbcom = 1;		memmove(BOOTARGS, KADDR(1024), BOOTARGSLEN);		memmove(BOOTLINE, KADDR(0x100), BOOTLINELEN);		bda = KADDR(0x400);		bda[0x13] = 639;		bda[0x14] = 639>>8;	}	/*	 *  parse configuration args from dos file plan9.ini	 */	cp = BOOTARGS;	/* where b.com leaves its config */	cp[BOOTARGSLEN-1] = 0;	/*	 * Strip out '\r', change '\t' -> ' '.	 */	p = cp;	for(q = cp; *q; q++){		if(*q == '\r')			continue;		if(*q == '\t')			*q = ' ';		*p++ = *q;	}	*p = 0;	n = getcfields(cp, line, MAXCONF, "\n");	for(i = 0; i < n; i++){		if(*line[i] == '#')			continue;		cp = strchr(line[i], '=');		if(cp == 0)			continue;		*cp++ = 0;		if(cp - line[i] >= NAMELEN+1)			*(line[i]+NAMELEN-1) = 0;		confname[nconf] = line[i];		confval[nconf] = cp;		nconf++;	}}/* * Vecinit is the first hook we have into configuring the machine, * so we do it all here. A pox on special fileserver code. * We do more in meminit below. */voidvecinit(void){	options();}intcistrcmp(char* a, char* b){	int ac, bc;	for(;;){		ac = *a++;		bc = *b++;		if(ac >= 'A' && ac <= 'Z')			ac = 'a' + (ac - 'A');		if(bc >= 'A' && bc <= 'Z')			bc = 'a' + (bc - 'A');		ac -= bc;		if(ac)			return ac;		if(bc == 0)			break;	}	return 0;}intcistrncmp(char *a, char *b, int n){	unsigned ac, bc;	while(n > 0){		ac = *a++;		bc = *b++;		n--;		if(ac >= 'A' && ac <= 'Z')			ac = 'a' + (ac - 'A');		if(bc >= 'A' && bc <= 'Z')			bc = 'a' + (bc - 'A');		ac -= bc;		if(ac)			return ac;		if(bc == 0)			break;	}	return 0;}char*getconf(char *name){	int i;	for(i = 0; i < nconf; i++)		if(cistrcmp(confname[i], name) == 0)			return confval[i];	return 0;}/* memory map; this kernel will see MAXMEG megabytes of RAM at most.  */#ifndef MAXMEG#define MAXMEG 1791	/* 1.75GB-1MB, to avoid overshooting into PCI space */#endifchar mmap[MAXMEG+2];Mconf mconf;static voidmconfinit(void){	long x, i, j;	ulong ktop;	Mbank *mbp;	uchar *bda;	/*	 *  size memory above 1 meg. Kernel sits at 1 meg.  We	 *  only recognize MB size chunks.	 */	memset(mmap, ' ', sizeof(mmap));	x = 0x12345678;	for(i = 1; i <= MAXMEG; i++){		/*		 *  write the first & last word in a megabyte of memory		 */		*mapaddr(KZERO|(i*MB)) = x;		*mapaddr(KZERO|((i+1)*MB-BY2WD)) = x;		/*		 *  write the first and last word in all previous megs to		 *  handle address wrap around		 */		for(j = 1; j < i; j++){			*mapaddr(KZERO|(j*MB)) = ~x;			*mapaddr(KZERO|((j+1)*MB-BY2WD)) = ~x;		}		/*		 *  check for correct value		 */		if(*mapaddr(KZERO|(i*MB)) == x && *mapaddr(KZERO|((i+1)*MB-BY2WD)) == x)			mmap[i] = 'x';		x += 0x3141526;	}	/*	 * bank[0] goes from the end of the bootstrap structures to ~640k.	 * want to use this up first for ialloc because sparemem	 * will want a large contiguous chunk.	 */	mbp = mconf.bank;	mbp->base = PADDR(CPU0MACH+BY2PG);	bda = (uchar*)(KZERO|0x400);	mbp->limit = ((bda[0x14]<<8)|bda[0x13])*1024;	mbp++;	/*	 *  bank[1] usually goes from the end of kernel bss to the end of memory	 */	ktop = PGROUND((ulong)end);	ktop = PADDR(ktop);	mbp->base = ktop;	for(i = 1; mmap[i] == 'x'; i++)		;	mbp->limit = i*MB;	mconf.topofmem = mbp->limit;	mbp++;	/*	 * Look for any other chunks of memory.	 */	for(; i <= MAXMEG; i++){		if(mmap[i] == 'x'){			mbp->base = i*MB;			for(j = i+1; mmap[j] == 'x'; j++)				;			mbp->limit = j*MB;			mconf.topofmem = j*MB;			mbp++;			if((mbp - mconf.bank) >= MAXBANK)				break;		}	}	mconf.nbank = mbp - mconf.bank;}ulongmeminit(void){	conf.nmach = 1;	mconfinit();	mmuinit();	trapinit();	/*	 * This is not really right, but the port code assumes	 * a linear memory array and this is as close as we can	 * get to satisfying that.	 * Dancing around the 'port' code is all just an ugly hack	 * anyway.	 */	return mconf.topofmem;}voiduserinit(void (*f)(void), void *arg, char *text){	User *p;	p = newproc();	/*	 * Kernel Stack.	 * The -4 is because the path sched()->gotolabel()->init0()->f()	 * uses a stack location without creating any local space.	 */	p->sched.pc = (ulong)init0;	p->sched.sp = (ulong)p->stack + sizeof(p->stack) - 4;	p->start = f;	p->text = text;	p->arg = arg;	dofilter(p->time+0, C0a, C0b, 1);	dofilter(p->time+1, C1a, C1b, 1);	dofilter(p->time+2, C2a, C2b, 1);	ready(p);}static int useuart;static void (*intrputs)(char*, int);static intpcgetc(void){	int c;	if(c = kbdgetc())		return c;	if(useuart)		return uartgetc();	return 0;}static voidpcputc(int c){	if(predawn)		cgaputc(c);	if(useuart)		uartputc(c);}static voidpcputs(char* s, int n){	if(!predawn)		cgaputs(s, n);	if(intrputs)		(*intrputs)(s, n);}voidconsinit(void (*puts)(char*, int)){	char *p;	int baud, port;	kbdinit();	consgetc = pcgetc;	consputc = pcputc;	consputs = pcputs;	intrputs = puts;	if((p = getconf("console")) == 0 || cistrcmp(p, "cga") == 0)		return;	port = strtoul(p, 0, 0);	baud = 0;	if(p = getconf("baud"))		baud = strtoul(p, 0, 0);	if(baud == 0)		baud = 9600;	uartspecial(port, kbdchar, conschar, baud);	useuart = 1;}voidconsreset(void){}voidfirmware(void){	char *p;	/*	 * Always called splhi().	 */	if((p = getconf("reset")) && cistrcmp(p, "manual") == 0){		predawn = 1;		print("\nHit Reset\n");		for(;;);	}	pcireset();	i8042reset();}intisaconfig(char *class, int ctlrno, ISAConf *isa){	char cc[NAMELEN], *p, *q, *r;	int n;	sprint(cc, "%s%d", class, ctlrno);	for(n = 0; n < nconf; n++){		if(cistrncmp(confname[n], cc, NAMELEN))			continue;		isa->nopt = 0;		p = confval[n];		while(*p){			while(*p == ' ' || *p == '\t')				p++;			if(*p == '\0')				break;			if(cistrncmp(p, "type=", 5) == 0){				p += 5;				for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){					if(*p == '\0' || *p == ' ' || *p == '\t')						break;					*q = *p++;				}				*q = '\0';			}			else if(cistrncmp(p, "port=", 5) == 0)				isa->port = strtoul(p+5, &p, 0);			else if(cistrncmp(p, "irq=", 4) == 0)				isa->irq = strtoul(p+4, &p, 0);			else if(cistrncmp(p, "dma=", 4) == 0)				isa->dma = strtoul(p+4, &p, 0);			else if(cistrncmp(p, "mem=", 4) == 0)				isa->mem = strtoul(p+4, &p, 0);			else if(cistrncmp(p, "size=", 5) == 0)				isa->size = strtoul(p+5, &p, 0);			else if(cistrncmp(p, "freq=", 5) == 0)				isa->freq = strtoul(p+5, &p, 0);			else if(isa->nopt < NISAOPT){				r = isa->opt[isa->nopt];				while(*p && *p != ' ' && *p != '\t'){					*r++ = *p++;					if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)						break;				}				*r = '\0';				isa->nopt++;			}			while(*p && *p != ' ' && *p != '\t')				p++;		}		return 1;	}	return 0;}voidlockinit(void){}voidlaunchinit(void){}voidlights(int, int){}/* in assembly languageFloatfamd(Float a, int b, int c, int d){	return ((a+b) * c) / d;}ulongfdf(Float a, int b){	return a / b;}*/

⌨️ 快捷键说明

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