📄 main.c
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "ureg.h"#include "init.h"#include "pool.h"Mach *m;Proc *up;Conf conf;int noprint;voidmain(void){ mmuinvalidate(); /* zero out bss */ memset(edata, 0, end-edata); /* point to Mach structure */ m = (Mach*)MACHADDR; memset(m, 0, sizeof(Mach)); m->ticks = 1; active.machs = 1; rs232power(1); quotefmtinstall(); iprint("\nPlan 9 bitsy kernel\n"); confinit(); xinit(); mmuinit(); machinit(); trapinit(); sa1110_uartsetup(1); dmainit(); screeninit(); printinit(); /* from here on, print works, before this we need iprint */ clockinit(); procinit0(); initseg(); links(); chandevreset(); pageinit(); swapinit(); userinit(); powerinit(); schedinit();}/* need to do better */voidreboot(void*, void*, ulong){ exit(0);}/* * exit kernel either on a panic or user request */voidexit(int ispanic){ void (*f)(void); USED(ispanic); delay(1000); iprint("it's a wonderful day to die\n"); cacheflush(); mmuinvalidate(); mmudisable(); f = nil; (*f)();}static uchar *sp;/* * starting place for first process */voidinit0(void){ 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()){ ksetenv("terminal", "bitsy", 0); ksetenv("cputype", "arm", 0); if(cpuserver) ksetenv("service", "cpu", 0); else ksetenv("service", "terminal", 0); poperror(); } kproc("alarm", alarmkproc, 0); kproc("power", powerkproc, 0); touser(sp);}/* * pass boot arguments to /boot */static uchar *pusharg(char *p){ int n; n = strlen(p)+1; sp -= n; memmove(sp, p, n); return sp;}static voidbootargs(ulong base){ int i, ac; uchar *av[32]; uchar *bootpath; uchar **lsp; /* * the sizeof(Sargs) is to make the validaddr check in * trap.c's syscall() work even when we have less than the * max number of args. */ sp = (uchar*)base + BY2PG - sizeof(Sargs); bootpath = pusharg("/boot/boot"); ac = 0; av[ac++] = pusharg("boot"); /* 4 byte word align stack */ sp = (uchar*)((ulong)sp & ~3); /* build argc, argv on stack */ sp -= (ac+1)*sizeof(sp); lsp = (uchar**)sp; for(i = 0; i < ac; i++) *lsp++ = av[i] + ((USTKTOP - BY2PG) - base); *lsp = 0; /* push argv onto stack */ sp -= BY2WD; lsp = (uchar**)sp; *lsp = sp + BY2WD + ((USTKTOP - BY2PG) - base); /* push pointer to "/boot" */ sp -= BY2WD; lsp = (uchar**)sp; *lsp = bootpath + ((USTKTOP - BY2PG) - base); /* leave space for where the initcode's caller's return PC would normally reside */ sp -= BY2WD; /* relocate stack to user's virtual addresses */ sp += (USTKTOP - BY2PG) - base;}/* * create the first process */voiduserinit(void){ Proc *p; Segment *s; KMap *k; Page *pg; /* no processes yet */ up = nil; 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); /* * Kernel Stack */ 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); k = kmap(pg); bootargs(VA(k)); kunmap(k); /* * Text */ s = newseg(SG_TEXT, UTZERO, 1); 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);}/* * set mach dependent process state for a new process */voidprocsetup(Proc *p){ p->fpstate = FPinit;}/* * Save the mach dependent part of the process state. */voidprocsave(Proc *p){ USED(p);}/* place holder *//* * dummy since rdb is not included */voidrdb(void){}/* * probe the last location in a meg of memory, make sure it's not * reflected into something else we've already found. */intprobemem(ulong addr){ int i; ulong *p; ulong a; addr += OneMeg - sizeof(ulong); p = (ulong*)addr; *p = addr; for(i=0; i<nelem(conf.mem); i++){ for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){ p = (ulong*)a; *p = 0; } } p = (ulong*)addr; if(*p != addr) return -1; return 0;}/* * we assume that the kernel is at the beginning of one of the * contiguous chunks of memory. */voidconfinit(void){ int i, j; ulong addr; ulong ktop; /* find first two contiguous sections of available memory */ addr = PHYSDRAM0; for(i=0; i<nelem(conf.mem); i++){ conf.mem[i].base = addr; conf.mem[i].limit = addr; } for(j=0; j<nelem(conf.mem); j++){ conf.mem[j].base = addr; conf.mem[j].limit = addr; for(i = 0; i < 512; i++){ if(probemem(addr) == 0) break; addr += OneMeg; } for(; i < 512; i++){ if(probemem(addr) < 0) break; addr += OneMeg; conf.mem[j].limit = addr; } } conf.npage = 0; for(i=0; i<nelem(conf.mem); i++){ /* take kernel out of allocatable space */ ktop = PGROUND((ulong)end); if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit) conf.mem[i].base = ktop; /* zero memory */ memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base); conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG; conf.npage += conf.mem[i].npage; } if(conf.npage > 16*MB/BY2PG){ conf.upages = (conf.npage*60)/100; imagmem->minarena = 4*1024*1024; }else conf.upages = (conf.npage*40)/100; conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; /* only one processor */ conf.nmach = 1; /* set up other configuration parameters */ conf.nproc = 100; conf.nswap = conf.npage*3; conf.nswppo = 4096; conf.nimage = 200; conf.monitor = 1; conf.copymode = 0; /* copy on write */}GPIOregs *gpioregs;ulong *egpioreg = (ulong*)EGPIOREGS;PPCregs *ppcregs;MemConfRegs *memconfregs;PowerRegs *powerregs;ResetRegs *resetregs;/* * configure the machine */voidmachinit(void){ /* set direction of SA1110 io pins and select alternate functions for some */ gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs)); gpioregs->direction = GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o |GPIO_COM_RTS_o; gpioregs->rising = 0; gpioregs->falling = 0; gpioregs->altfunc |= GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o |GPIO_SSP_CLK_i; /* map in special H3650 io pins */ egpioreg = mapspecial(EGPIOREGS, sizeof(ulong)); /* map in peripheral pin controller (ssp will need it) */ ppcregs = mapspecial(PPCREGS, sizeof(PPCregs)); /* SA1110 power management */ powerregs = mapspecial(POWERREGS, sizeof(PowerRegs)); /* memory configuraton */ memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs)); /* reset controller */ resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));}/* * manage egpio bits */static ulong egpiosticky;voidegpiobits(ulong bits, int on){ if(on) egpiosticky |= bits; else egpiosticky &= ~bits; *egpioreg = egpiosticky;}voidrs232power(int on){ egpiobits(EGPIO_rs232_power, on); delay(50);}voidaudioamppower(int on){ egpiobits(EGPIO_audio_power, on); delay(50);}voidaudioicpower(int on){ egpiobits(EGPIO_audio_ic_power, on); delay(50);}voidirpower(int on){ egpiobits(EGPIO_ir_power, on); delay(50);}voidlcdpower(int on){ egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on); delay(50);}voidflashprogpower(int on){ egpiobits(EGPIO_prog_flash, on);}/* here on hardware reset */voidresettrap(void){}/* * for drivers that used to run on x86's */voidoutb(ulong a, uchar v){ *(uchar*)a = v;}voidouts(ulong a, ushort v){ *(ushort*)a = v;}voidoutss(ulong a, void *p, int n){ ushort *sp = p; while(n-- > 0) *(ushort*)a = *sp++;}voidoutl(ulong a, ulong v){ *(ulong*)a = v;}ucharinb(ulong a){ return *(uchar*)a;}ushortins(ulong a){ return *(ushort*)a;}voidinss(ulong a, void *p, int n){ ushort *sp = p; while(n-- > 0) *sp++ = *(ushort*)a;}ulonginl(ulong a){ return *(ulong*)a;}char*getconf(char*){ return nil;}long_xdec(long *p){ int s; long v; s = splhi(); v = --*p; splx(s); return v;}void_xinc(long *p){ int s; s = splhi(); ++*p; splx(s);}intcmpswap(long *addr, long old, long new){ int r, s; s = splhi(); if(r = (*addr==old)) *addr = new; splx(s); return r;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -