📄 startup.c
字号:
stopclocks(); Syssize = eSysmap - Sysmap; fpage = btoc(K0_TO_PHYS((unsigned)end)); /* first page phys mem */ getargs(argc, argv, envp); fpage = xprinit(fpage); /* initialize XPRBUG buffer */ mapinit(fpage); /* initialize system maps */ /* * In mapinit we initialize the kernel stack, so now we can * handle exceptions. For some systems, cninit will cause * an exception while doing badaddr probes. * Once cninit is done we can do kernel printfs thru the Ultrix * driver (rather than thru console call backs). */ cninit(); printstate |= CONSPRINT; /* We can print on the console */ /* * We can do mprintfs after kmeminit is done in mapinit. */ printstate = printstate | MEMPRINT; appendflg = 1; printf(version); printf("real mem = %d\n", ctob(physmem)); printf("avail mem = %d\n", ctob(maxmem)); printf("using %d buffers containing %d bytes of memory\n", nbuf, bufpages * CLBYTES); if (cpup->flags & SCS_START_SYSAPS) scs_start_sysaps(); configure(); /* auto config. */ getbootctlr(); /* Get logical controller */ appendflg = 0; /* done with startup config messages */ printf(""); (*(cpup->timer_action)); /* * on return from configure machine is at spl0() */ init_restartblk();}/* * Convert an ASCII string of hex characters to a binary number. */xtob(str) char *str;{ register int hexnum; if (str == NULL || *str == NULL) return(0); hexnum = 0; if (str[0] == '0' && str[1] == 'x') str = str + 2; for ( ; *str; str++) { if (*str >= '0' && *str <= '9') hexnum = hexnum * 16 + (*str - 48); else if (*str >= 'a' && *str <= 'f') hexnum = hexnum * 16 + (*str - 87); else if (*str >= 'A' && *str <= 'F') hexnum = hexnum * 16 + (*str - 55); } return(hexnum);}/* * Mapinit: * Initialize kernel memory allocation structures. The kernel now * has itself mapped virtual to physical from address 0x100000 to the * end of bss. *//* * Declare these as initialized data so we can patch them. */#ifdef MEMLIMITint memlimit = MEMLIMIT; /* to artificially reduce memory */#else MEMLIMITint memlimit = 0;#endif MEMLIMITint nbuf = 0; /* number of file system buffers */int nswbuf = 0; /* number of swap buffers */int bufpages = 0; /* file system buffer pages */int bufdebug = 0; /* buffer cache initialization messages */int clperbuf = 0; /* one buf struct for every clperbuf page clusters */ /* of cache */int pteperbuf = 2; /* we need two 4K ptes for each 8K buf */mapinit(fpage){ register int i,j; int maxbufs, base, residual; int maxbufpages, requestpages, tenpercent; unsigned mapvpn; caddr_t v, paddr; struct tlbinfo *wtlb; struct pte *umap; struct cpudata *pcpu; extern VEC_nofault(), VEC_trap(); extern (*causevec[])();#if PROFILING extern char eprol[], etext[]; extern char *s_lowpc; extern u_long s_textsize; extern struct phdr phdr;#endif PROFILING extern int bufcache; /* % of memory used for buffer cache data */ extern int cache_bufcache; /* cache the buffer cache? */ extern int maxusers; extern long usrptsize; int bcpages; /* * Invalidate entire tlb (including wired entries) */ for (i = 0; i < NTLBENTRIES; i++) if (i != TLBWIREDBASE) /* TLBWIREDBASE already used for mapping u area of idle proc for the boot cpu. So don't invalidate it */ invaltlb(i); /* * Size memory, by calling a routine thru the cpu switch. */ if ((i = (*(cpup->memsize))(fpage)) <= 0) panic("No memory sizing routine configured\n"); if ((cpu == DS_5400) || ( cpu == DS_5500)) { /* * On a Q bus, we need to grab 32K bytes of memory * for the Qbus map registers. Here we simply use * the last 32Kb of physical memory. Note that the Qbus * map must be on a 32Kb boundary. * This causes us to lose at least 32Kb of memory. */ i -= (i % 8); /* make sure we'on 32Kb boundary */ i -= 8; /* lose the last 32Kb */ qmapbase = i * 4096; } if (memlimit && (i > btop(memlimit))) i = btop(memlimit); maxmem = physmem = freemem = i; /* * If we used adb (or something) on the kernel and set "Physmem" * to some value, then use that value for "physmem". * This allows us to run in less physical memory than the * machine really has. (rr's idea). */ if (Physmem >= MINMEM_PGS) { physmem = Physmem; } /* * Save the real amount of memory (or the above artificial * amount) to allow the sizer to accurately configure physmem * in the config file. `Physmem' was originally added for the * sizer utility - tomt */ Physmem = physmem; /* Let sizer know the size */ /* * Initialize error message buffer (at end of core). */#ifdef notdef maxmem -= btoc(sizeof(struct msgbuf));#if NOMEMCACHE==1 pmsgbuf = (struct msgbuf *)PHYS_TO_K1((unsigned)ptob(maxmem));#else pmsgbuf = (struct msgbuf *)PHYS_TO_K0((unsigned)ptob(maxmem));#endif#ifndef SABLE if (pmsgbuf->msg_magic != MSG_MAGIC) for (i = 0; i < MSG_BSIZE; i++) pmsgbuf->msg_bufc[i] = 0;#endif#endif notdef /* * Initialization message print. */ /* * Determine how many buffers to allocate. * * Use bufcache% (a config'able option) of memory. * If bufpgs > (physmem - min mem reserved for system) * then set bufpgs to (physmem - min mem reserved for system). * Ensure that bufpages is at least 10% of memory. * * We allocate 1/2 as many swap buffer headers (nswbuf) * as file i/o buffers (nbuf), but never more than 256. * * NB: The maximum number of buffers is determined by sysptsize, * which determines how much of k0 is allocated to pte's for the * buffer cache. */ if (bufpages == 0) { /* * requestpages, maxbufpages, tenpercent are measured * in NBPG byte units. * * requestpages is what was requested in the config file. * maxbufpages is the upper limit of what is allowed. * tenpercent is the lower limit of what is allowed. * * As silly as this sounds, the upper limit can be lower * than the lower limit (even negative on minimum * configuration machines), so make sure that the upper * limit is >= tenpercent * * Since we only have MINMEM_PGS to guide us, and * since this number is only meaningful for kernels * with relatively small system table sizes, scale * up the estimate of the demands that these tables * make on memory as a function of maxusers when * computing the upper limit. * Allow for the buffer headers as well. * */ requestpages = (physmem * bufcache) / 100; maxbufpages = physmem - MINMEM_PGS - (maxusers/32) * ((1024*1024)/NBPG) /* 1MB/32 users */ - (sysptsize * sizeof(struct pte)) / NBPG - 1; /* * clperbuf is set to 1 (a historical value) for * uniprocessors, and 2 (no moving of physical * memory under a virtual address) for multi-processors. * Sanity test clperbuf on multiprocessors to * guarantee that buffer memory is not moved around. */ if (!clperbuf) /* hasn't been manually patched */ clperbuf = ((smp) ? 2 : 1); if (smp && clperbuf != 2) panic("buffer header allocation failure"); maxbufs = maxbufpages / CLSIZE / clperbuf; maxbufpages -= (maxbufs * sizeof(struct buf)) / NBPG; tenpercent = physmem / 10; if (maxbufpages < tenpercent) maxbufpages = tenpercent;if (bufdebug) {printf("startup: physmem %d bufcache %d requestpages %d\n", physmem, bufcache, requestpages);printf("startup: clperbuf %d maxbufs %d maxbufpages %d tenpercent %d\n", clperbuf, maxbufs, maxbufpages, tenpercent);} if (requestpages > maxbufpages) {if (bufdebug) {printf("startup: bufcache request of %d bytes reduced to %d bytes\n", requestpages*NBPG, maxbufpages*NBPG);} requestpages = maxbufpages; } /* bufpages is measured in page cluster units */ bufpages = requestpages / CLSIZE; } if (nbuf == 0) { /* nbuf is # of page cluster objects that fit in bufpages */ nbuf = (bufpages * CLSIZE) / clperbuf; } /* * Finally, check to make sure that the system page table is * big enough to map nbuf buffers. * Note: This assumes that on mips based systems that nothing * but the buffer cache uses the system page table. */ if (nbuf > (sysptsize / CLSIZE / pteperbuf)) {if (bufdebug) {printf("startup: nbufs reduced due to system page table size\n");} nbuf = (sysptsize / CLSIZE / pteperbuf); } if (nswbuf == 0) { nswbuf = (nbuf / 2) &~ 1; /* force even */ if (nswbuf > 256) nswbuf = 256; /* sanity */ }if (bufdebug) {printf("startup: bufpages %d nbuf %d nswbuf %d sysptsize %d\n", bufpages, nbuf, nswbuf, sysptsize);} /* * Allocate space for unmapped system data structures. * Next available unmapped kernel address is maintained in paddr; */#if NOMEMCACHE==1 paddr = (caddr_t)PHYS_TO_K1((u_int)ptob(fpage));#else paddr = (caddr_t)PHYS_TO_K0((u_int)ptob(fpage));#endif#define palloc(name, type, num) \ (name) = (type *)(paddr); \ (paddr) = (caddr_t)((name)+(num))#define palloclim(name, type, num, lim) \ (name) = (type *)(paddr); \ (paddr) = (caddr_t)((lim) = ((name)+(num))) palloc(buf, struct buf, nbuf); palloc(swbuf, struct buf, nswbuf); palloclim(gnode, struct gnode, ngnode, gnodeNGNODE); palloclim(file, struct file, nfile, fileNFILE); palloclim(proc, struct proc, nproc, procNPROC); palloc(umap, struct pte, nproc*UPAGES); palloc(wtlb, struct tlbinfo, nproc*NPAGEMAP); palloclim(text, struct text, ntext, textNTEXT); palloc(cfree, struct cblock, nclist); palloc(callout, struct callout, ncallout); palloc(swapmap, struct map, nswapmap = nproc * 2); /* * kernelmap must be large enough to allocate 3 page tables * per process (text, data, stack) */ palloc(kernelmap, struct map, nproc*3); palloc (flox, struct filock, flckinfo.recs ); palloc (flinotab, struct flino, flckinfo.fils ); palloc (kmemmap, struct map, (ekmempt - kmempt) - km_wmapsize); palloc (kmemwmap, struct map, km_wmapsize); palloc (kmemusage, struct kmemusage, (ekmempt - kmempt)); palloc(nch, struct nch, nchsize);#if PROFILING /* get some memory for the profiling routines to use */ s_textsize = 0; s_lowpc = phdr.lowpc = (char *) ROUNDDOWN((unsigned)eprol, HISTFRACTION*sizeof(HISTCOUNTER)); phdr.highpc = (char *) ROUNDUP((unsigned)etext, HISTFRACTION*sizeof(HISTCOUNTER)); s_textsize = phdr.highpc - phdr.lowpc; phdr.pc_bytes = (s_textsize / HISTFRACTION); cprintf("Profiling kernel, textsize=%d(%d) [%x..%x]\n", phdr.pc_bytes, s_textsize, phdr.lowpc, phdr.highpc); palloc(phdr.pc_buf, char, phdr.pc_bytes); cprintf("got pc_buf at %x\n", phdr.pc_buf);#if PROFTYPE == 2 || PROFTYPE == 3 phdr.bb_bytes = s_textsize / BB_SCALE; palloc(phdr.bb_buf, char, phdr.bb_bytes);#endif PROFTYPE == 2 | 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -