1*361Sbill /* init_main.c 3.8 07/12/80 */ 226Sbill 326Sbill #include "../h/param.h" 426Sbill #include "../h/systm.h" 526Sbill #include "../h/dir.h" 626Sbill #include "../h/user.h" 726Sbill #include "../h/filsys.h" 826Sbill #include "../h/mount.h" 926Sbill #include "../h/map.h" 1026Sbill #include "../h/proc.h" 1126Sbill #include "../h/inode.h" 1226Sbill #include "../h/seg.h" 1326Sbill #include "../h/conf.h" 1426Sbill #include "../h/buf.h" 1526Sbill #include "../h/mtpr.h" 1626Sbill #include "../h/pte.h" 1726Sbill #include "../h/clock.h" 1826Sbill #include "../h/vm.h" 1926Sbill #include "../h/cmap.h" 20348Sbill #include "../h/text.h" 2126Sbill 2226Sbill /* 2326Sbill * Initialization code. 2426Sbill * Called from cold start routine as 2526Sbill * soon as a stack and segmentation 2626Sbill * have been established. 2726Sbill * Functions: 2826Sbill * clear and free user core 2926Sbill * turn on clock 3026Sbill * hand craft 0th process 3126Sbill * call all initialization routines 3226Sbill * fork - process 0 to schedule 3326Sbill * - process 2 to page out 3426Sbill * - process 1 execute bootstrap 3526Sbill * 3626Sbill * loop at loc 13 (0xd) in user mode -- /etc/init 3726Sbill * cannot be executed. 3826Sbill */ 3926Sbill main(firstaddr) 4026Sbill { 41*361Sbill register int i; 4226Sbill 4326Sbill cpusid = mfpr(SID); /* get system identification */ 4426Sbill #ifdef FASTVAX 4526Sbill rqinit(); 4626Sbill #endif 4726Sbill startup(firstaddr); 4826Sbill if (lotsfree == 0) 4926Sbill lotsfree = LOTSFREE; 5026Sbill 5126Sbill /* 5226Sbill * set up system process 0 (swapper) 5326Sbill */ 5426Sbill 5526Sbill proc[0].p_p0br = (struct pte *)mfpr(P0BR); 5626Sbill proc[0].p_szpt = 1; 5726Sbill proc[0].p_addr = uaddr(&proc[0]); 5826Sbill proc[0].p_stat = SRUN; 5926Sbill proc[0].p_flag |= SLOAD|SSYS; 6026Sbill proc[0].p_nice = NZERO; 6126Sbill u.u_procp = &proc[0]; 6226Sbill u.u_cmask = CMASK; 63*361Sbill for (i = 1; i < sizeof(u.u_limit)/sizeof(u.u_limit[0]); i++) 64*361Sbill u.u_limit[i] = INFINITY; 6526Sbill clkstart(); 6626Sbill 6726Sbill /* 6826Sbill * Initialize devices and 6926Sbill * set up 'known' i-nodes 7026Sbill */ 7126Sbill 7226Sbill ihinit(); 7392Sbill bhinit(); 7426Sbill cinit(); 7526Sbill binit(); 7626Sbill bswinit(); 7726Sbill iinit(); 7826Sbill rootdir = iget(rootdev, (ino_t)ROOTINO); 7926Sbill rootdir->i_flag &= ~ILOCK; 8026Sbill u.u_cdir = iget(rootdev, (ino_t)ROOTINO); 8126Sbill u.u_cdir->i_flag &= ~ILOCK; 8226Sbill u.u_rdir = NULL; 8326Sbill u.u_dmap = zdmap; 8426Sbill u.u_smap = zdmap; 8526Sbill 8626Sbill /* 8726Sbill * make page-out daemon (process 2) 8826Sbill * the daemon has ctopt(NSWBUF*CLSIZE*KLMAX) pages of page 8926Sbill * table so that it can map dirty pages into 9026Sbill * its address space during asychronous pushes. 9126Sbill */ 9226Sbill 9326Sbill mpid = 1; 9426Sbill proc[0].p_szpt = clrnd(ctopt(NSWBUF*CLSIZE*KLMAX + UPAGES)); 9526Sbill proc[1].p_stat = SZOMB; /* force it to be in proc slot 2 */ 9626Sbill if (newproc(0)) { 9726Sbill proc[2].p_flag |= SLOAD|SSYS; 9826Sbill proc[2].p_dsize = u.u_dsize = NSWBUF*CLSIZE*KLMAX; 9926Sbill pageout(); 10026Sbill } 10126Sbill 10226Sbill /* 10326Sbill * make init process and 10426Sbill * enter scheduling loop 10526Sbill */ 10626Sbill 10726Sbill mpid = 0; 10826Sbill proc[1].p_stat = 0; 10926Sbill proc[0].p_szpt = CLSIZE; 11026Sbill if (newproc(0)) { 11126Sbill expand(clrnd((int)btoc(szicode)), P0BR); 112348Sbill swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap); 113135Sbill (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 11426Sbill /* 11526Sbill * Return goes to loc. 0 of user init 11626Sbill * code just copied out. 11726Sbill */ 11826Sbill return; 11926Sbill } 12026Sbill proc[0].p_szpt = 1; 12126Sbill sched(); 12226Sbill } 12326Sbill 12426Sbill /* 12526Sbill * iinit is called once (from main) 12626Sbill * very early in initialization. 12726Sbill * It reads the root's super block 12826Sbill * and initializes the current date 12926Sbill * from the last modified date. 13026Sbill * 13126Sbill * panic: iinit -- cannot read the super 13226Sbill * block. Usually because of an IO error. 13326Sbill */ 13426Sbill iinit() 13526Sbill { 13626Sbill register struct buf *cp, *bp; 13726Sbill register struct filsys *fp; 13826Sbill register unsigned i, j; 13926Sbill 14026Sbill (*bdevsw[major(rootdev)].d_open)(rootdev, 1); 14126Sbill bp = bread(rootdev, SUPERB); 14226Sbill cp = geteblk(); 14326Sbill if(u.u_error) 14426Sbill panic("iinit"); 14526Sbill bcopy(bp->b_un.b_addr, cp->b_un.b_addr, sizeof(struct filsys)); 14626Sbill brelse(bp); 14726Sbill mount[0].m_bufp = cp; 14826Sbill mount[0].m_dev = rootdev; 14926Sbill fp = cp->b_un.b_filsys; 15026Sbill fp->s_flock = 0; 15126Sbill fp->s_ilock = 0; 15226Sbill fp->s_ronly = 0; 15326Sbill fp->s_lasti = 1; 15426Sbill fp->s_nbehind = 0; 15526Sbill /* on boot, read VAX TODR register (GMT 10 ms. 15626Sbill * clicks into current year) and set software time 15726Sbill * in 'int time' (GMT seconds since year YRREF) 15826Sbill */ 15926Sbill for (i = 0 , j = YRREF ; j < YRCURR ; j++) 16026Sbill i += (SECYR + (j%4?0:SECDAY)) ; 16126Sbill time = udiv(mfpr(TODR),100) + i ; 16226Sbill bootime = time; 16326Sbill } 16426Sbill 16526Sbill /* 16626Sbill * This is the set of buffers proper, whose heads 16726Sbill * were declared in buf.h. There can exist buffer 16826Sbill * headers not pointing here that are used purely 16926Sbill * as arguments to the I/O routines to describe 17026Sbill * I/O to be done-- e.g. swap headers swbuf[] for 17126Sbill * swapping. 17226Sbill */ 173108Sbill char buffers[NBUF][BSIZE]; 17426Sbill 17526Sbill /* 17626Sbill * Initialize the buffer I/O system by freeing 17726Sbill * all buffers and setting all device buffer lists to empty. 17826Sbill * 17926Sbill * SHOULD USE MEMALL HERE!!! 18026Sbill */ 18126Sbill binit() 18226Sbill { 18326Sbill register struct buf *bp; 18426Sbill register struct buf *dp; 18526Sbill register int i; 18626Sbill struct bdevsw *bdp; 187306Sbill struct swdevt *swp; 18826Sbill 18926Sbill bfreelist.b_forw = bfreelist.b_back = 19026Sbill bfreelist.av_forw = bfreelist.av_back = &bfreelist; 19126Sbill for (i=0; i<NBUF; i++) { 19226Sbill bp = &buf[i]; 19326Sbill bp->b_dev = NODEV; 19426Sbill bp->b_un.b_addr = buffers[i]; 19526Sbill bp->b_back = &bfreelist; 19626Sbill bp->b_forw = bfreelist.b_forw; 19726Sbill bfreelist.b_forw->b_back = bp; 19826Sbill bfreelist.b_forw = bp; 19926Sbill bp->b_flags = B_BUSY; 20026Sbill brelse(bp); 20126Sbill } 20226Sbill for (bdp = bdevsw; bdp->d_open; bdp++) { 20326Sbill dp = bdp->d_tab; 20426Sbill if(dp) { 20526Sbill dp->b_forw = dp; 20626Sbill dp->b_back = dp; 20726Sbill } 20826Sbill nblkdev++; 20926Sbill } 210306Sbill /* 211306Sbill * Count swap devices, and adjust total swap space available. 212306Sbill * Some of this space will not be available until a vswapon() 213306Sbill * system is issued, usually when the system goes multi-user. 214306Sbill */ 215306Sbill nswdev = 0; 216306Sbill for (swp = swdevt; swp->sw_dev; swp++) 217306Sbill nswdev++; 218306Sbill if (nswdev == 0) 219306Sbill panic("binit"); 220306Sbill nswap *= nswdev; 221306Sbill maxpgio *= nswdev; 222306Sbill swfree(0); 22326Sbill } 22426Sbill 22526Sbill /* 22626Sbill * Initialize linked list of free swap 22726Sbill * headers. These do not actually point 22826Sbill * to buffers, but rather to pages that 22926Sbill * are being swapped in and out. 23026Sbill */ 23126Sbill bswinit() 23226Sbill { 23326Sbill register int i; 23426Sbill 23526Sbill bswlist.av_forw = &swbuf[0]; 23626Sbill for (i=0; i<NSWBUF-1; i++) 23726Sbill swbuf[i].av_forw = &swbuf[i+1]; 23826Sbill swbuf[NSWBUF-1].av_forw = NULL; 23926Sbill } 240