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

📄 main.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"io.h"#include	"init.h"#include	"pool.h"Conf	conf;FPsave	initfp;voidmain(void){	memset(edata, 0, (ulong)end-(ulong)edata);	conf.nmach = 1;	machinit();	ioinit();	i8250console();	quotefmtinstall();	print("\nPlan 9\n");	confinit();	xinit();	raveninit();	trapinit();	printinit();	cpuidprint();	mmuinit();	hwintrinit();	clockinit();	kbdinit();	procinit0();	initseg();	timersinit();	links();	chandevreset();	pageinit();	swapinit();	fpsave(&initfp);	initfp.fpscr = 0;	userinit();	schedinit();}voidmachinit(void){	memset(m, 0, sizeof(Mach));	m->cputype = getpvr()>>16;	/*	 * For polled uart output at boot, need	 * a default delay constant. 100000 should	 * be enough for a while. Cpuidentify will	 * calculate the real value later.	 */	m->loopconst = 100000;	/* turn on caches */	puthid0(gethid0() | BIT(16) | BIT(17));	active.machs = 1;	active.exiting = 0;}voidcpuidprint(void){	char *id;	id = "unknown PowerPC";	switch(m->cputype) {	case 9:		id = "PowerPC 604e";		break;	}	print("cpu0: %s\n", id);}static struct{	char	*name;	char *val;}plan9ini[] ={	{ "console", "0" },	{ "ether0", "type=2114x" },};char*getconf(char *name){	int i;	for(i = 0; i < nelem(plan9ini); i++)		if(cistrcmp(name, plan9ini[i].name) == 0)			return plan9ini[i].val;	return nil;}voidinit0(void){//	char **p, *q, name[KNAMELEN];//	int n;	char buf[2*KNAMELEN];	up->nerrlab = 0;	spllo();	/*	 * These are o.k. because rootinit is null.	 * Then early kproc's will have a root and dot.	 */	up->slash = namec("#/", Atodir, 0, 0);	pathclose(up->slash->path);	up->slash->path = newpath("/");	up->dot = cclone(up->slash);	chandevinit();	if(!waserror()){		snprint(buf, sizeof(buf), "power %s mtx", conffile);		ksetenv("terminal", buf, 0);		ksetenv("cputype", "power", 0);		if(cpuserver)			ksetenv("service", "cpu", 0);		else			ksetenv("service", "terminal", 0);		/*		for(p = confenv; *p; p++) {			q = strchr(p[0], '=');			if(q == 0)				continue;			n = q-p[0];			if(n >= KNAMELEN)				n = KNAMELEN-1;			memmove(name, p[0], n);			name[n] = 0;			if(name[0] != '*')				ksetenv(name, q+1, 0);			ksetenv(name, q+1, 1);		}*/		poperror();	}	kproc("alarm", alarmkproc, 0);	kproc("mmusweep", mmusweep, 0);	touser((void*)(USTKTOP-8));}voiduserinit(void){	Proc *p;	Segment *s;	KMap *k;	Page *pg;	p = newproc();	p->pgrp = newpgrp();	p->egrp = smalloc(sizeof(Egrp));	p->egrp->ref = 1;	p->fgrp = dupfgrp(nil);	p->rgrp = newrgrp();	p->procmode = 0640;	kstrdup(&eve, "");	kstrdup(&p->text, "*init*");	kstrdup(&p->user, eve);	p->fpstate = FPinit;	/*	 * Kernel Stack	 *	 * N.B. The -12 for the stack pointer is important.	 *	4 bytes for gotolabel's return PC	 */	p->sched.pc = (ulong)init0;	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);	/*	 * User Stack	 */	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);	p->seg[SSEG] = s;	pg = newpage(1, 0, USTKTOP-BY2PG);	segpage(s, pg);	/*	 * Text	 */	s = newseg(SG_TEXT, UTZERO, 1);	s->flushme++;	p->seg[TSEG] = s;	pg = newpage(1, 0, UTZERO);	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));	segpage(s, pg);	k = kmap(s->map[0]->pages[0]);	memmove((ulong*)VA(k), initcode, sizeof initcode);	kunmap(k);	ready(p);}/* still to do */voidreboot(void*, void*, ulong){	exit(0);}voidexit(int ispanic){	int ms, once;	lock(&active);	if(ispanic)		active.ispanic = ispanic;	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)		active.ispanic = 0;	once = active.machs & (1<<m->machno);	active.machs &= ~(1<<m->machno);	active.exiting = 1;	unlock(&active);	if(once)		print("cpu%d: exiting\n", m->machno);	spllo();	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){		delay(TK2MS(2));		if(active.machs == 0 && consactive() == 0)			break;	}	if(active.ispanic && m->machno == 0){		if(cpuserver)			delay(10000);		else if(conf.monitor)			for(;;);	}	else		delay(1000);	watchreset();}/* *  set up floating point for a new process */voidprocsetup(Proc *p){	p->fpstate = FPinit;}/* *  Save the mach dependent part of the process state. */voidprocsave(Proc *p){	if(p->fpstate == FPactive){		if(p->state != Moribund)			fpsave(&up->fpsave);		p->fpstate = FPinactive;	}}voidconfinit(void){	char *p;	int userpcnt;	ulong pa, kpages;	extern ulong memsize;	/* passed in from ROM monitor */	if(p = getconf("*kernelpercent"))		userpcnt = 100 - strtol(p, 0, 0);	else		userpcnt = 0;	pa = PGROUND(PADDR(end));	conf.mem[0].npage = memsize/BY2PG;	conf.mem[0].base = pa;	conf.npage = conf.mem[0].npage;	conf.nmach = 1;	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;	if(cpuserver)		conf.nproc *= 3;	if(conf.nproc > 2000)		conf.nproc = 2000;	conf.nimage = 200;	conf.nswap = conf.nproc*80;	conf.nswppo = 4096;	conf.copymode = 0;			/* copy on write */	if(cpuserver) {		if(userpcnt < 10)			userpcnt = 70;		kpages = conf.npage - (conf.npage*userpcnt)/100;		/*		 * Hack for the big boys. Only good while physmem < 4GB.		 * Give the kernel a max. of 16MB + enough to allocate the		 * page pool.		 * This is an overestimate as conf.upages < conf.npages.		 * The patch of nimage is a band-aid, scanning the whole		 * page list in imagereclaim just takes too long.		 */		if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){			kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;			conf.nimage = 2000;			kpages += (conf.nproc*KSTACK)/BY2PG;		}	} else {		if(userpcnt < 10) {			if(conf.npage*BY2PG < 16*MB)				userpcnt = 40;			else				userpcnt = 60;		}		kpages = conf.npage - (conf.npage*userpcnt)/100;		/*		 * Make sure terminals with low memory get at least		 * 4MB on the first Image chunk allocation.		 */		if(conf.npage*BY2PG < 16*MB)			imagmem->minarena = 4*1024*1024;	}	conf.upages = conf.npage - kpages;	conf.ialloc = (kpages/2)*BY2PG;	/*	 * Guess how much is taken by the large permanent	 * datastructures. Mntcache and Mntrpc are not accounted for	 * (probably ~300KB).	 */	kpages *= BY2PG;	kpages -= conf.upages*sizeof(Page)		+ conf.nproc*sizeof(Proc)		+ conf.nimage*sizeof(Image)		+ conf.nswap		+ conf.nswppo*sizeof(Page);	mainmem->maxsize = kpages;	if(!cpuserver){		/*		 * give terminals lots of image memory, too; the dynamic		 * allocation will balance the load properly, hopefully.		 * be careful with 32-bit overflow.		 */		imagmem->maxsize = kpages;	}//	conf.monitor = 1;	/* BUG */}static 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;}intisaconfig(char *class, int ctlrno, ISAConf *isa){	int i;	char cc[KNAMELEN], *p;	sprint(cc, "%s%d", class, ctlrno);	p = getconf(cc);	if(p == 0)		return 0;	isa->nopt = tokenize(p, isa->opt, NISAOPT);	for(i = 0; i < isa->nopt; i++){		p = isa->opt[i];		if(cistrncmp(p, "type=", 5) == 0)			isa->type = p + 5;		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);	}	return 1;}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;}

⌨️ 快捷键说明

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