1*348Sbill /* init_main.c 3.7 07/06/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" 20*348Sbill #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 { 4126Sbill 4226Sbill cpusid = mfpr(SID); /* get system identification */ 4326Sbill #ifdef FASTVAX 4426Sbill rqinit(); 4526Sbill #endif 4626Sbill startup(firstaddr); 4726Sbill if (lotsfree == 0) 4826Sbill lotsfree = LOTSFREE; 4926Sbill 5026Sbill /* 5126Sbill * set up system process 0 (swapper) 5226Sbill */ 5326Sbill 5426Sbill proc[0].p_p0br = (struct pte *)mfpr(P0BR); 5526Sbill proc[0].p_szpt = 1; 5626Sbill proc[0].p_addr = uaddr(&proc[0]); 5726Sbill proc[0].p_stat = SRUN; 5826Sbill proc[0].p_flag |= SLOAD|SSYS; 5926Sbill proc[0].p_nice = NZERO; 6026Sbill u.u_procp = &proc[0]; 6126Sbill u.u_cmask = CMASK; 6226Sbill clkstart(); 6326Sbill 6426Sbill /* 6526Sbill * Initialize devices and 6626Sbill * set up 'known' i-nodes 6726Sbill */ 6826Sbill 6926Sbill ihinit(); 7092Sbill bhinit(); 7126Sbill cinit(); 7226Sbill binit(); 7326Sbill bswinit(); 7426Sbill iinit(); 7526Sbill rootdir = iget(rootdev, (ino_t)ROOTINO); 7626Sbill rootdir->i_flag &= ~ILOCK; 7726Sbill u.u_cdir = iget(rootdev, (ino_t)ROOTINO); 7826Sbill u.u_cdir->i_flag &= ~ILOCK; 7926Sbill u.u_rdir = NULL; 8026Sbill u.u_dmap = zdmap; 8126Sbill u.u_smap = zdmap; 8226Sbill 8326Sbill /* 8426Sbill * make page-out daemon (process 2) 8526Sbill * the daemon has ctopt(NSWBUF*CLSIZE*KLMAX) pages of page 8626Sbill * table so that it can map dirty pages into 8726Sbill * its address space during asychronous pushes. 8826Sbill */ 8926Sbill 9026Sbill mpid = 1; 9126Sbill proc[0].p_szpt = clrnd(ctopt(NSWBUF*CLSIZE*KLMAX + UPAGES)); 9226Sbill proc[1].p_stat = SZOMB; /* force it to be in proc slot 2 */ 9326Sbill if (newproc(0)) { 9426Sbill proc[2].p_flag |= SLOAD|SSYS; 9526Sbill proc[2].p_dsize = u.u_dsize = NSWBUF*CLSIZE*KLMAX; 9626Sbill pageout(); 9726Sbill } 9826Sbill 9926Sbill /* 10026Sbill * make init process and 10126Sbill * enter scheduling loop 10226Sbill */ 10326Sbill 10426Sbill mpid = 0; 10526Sbill proc[1].p_stat = 0; 10626Sbill proc[0].p_szpt = CLSIZE; 10726Sbill if (newproc(0)) { 10826Sbill expand(clrnd((int)btoc(szicode)), P0BR); 109*348Sbill swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap); 110135Sbill (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 11126Sbill /* 11226Sbill * Return goes to loc. 0 of user init 11326Sbill * code just copied out. 11426Sbill */ 11526Sbill return; 11626Sbill } 11726Sbill proc[0].p_szpt = 1; 11826Sbill sched(); 11926Sbill } 12026Sbill 12126Sbill /* 12226Sbill * iinit is called once (from main) 12326Sbill * very early in initialization. 12426Sbill * It reads the root's super block 12526Sbill * and initializes the current date 12626Sbill * from the last modified date. 12726Sbill * 12826Sbill * panic: iinit -- cannot read the super 12926Sbill * block. Usually because of an IO error. 13026Sbill */ 13126Sbill iinit() 13226Sbill { 13326Sbill register struct buf *cp, *bp; 13426Sbill register struct filsys *fp; 13526Sbill register unsigned i, j; 13626Sbill 13726Sbill (*bdevsw[major(rootdev)].d_open)(rootdev, 1); 13826Sbill bp = bread(rootdev, SUPERB); 13926Sbill cp = geteblk(); 14026Sbill if(u.u_error) 14126Sbill panic("iinit"); 14226Sbill bcopy(bp->b_un.b_addr, cp->b_un.b_addr, sizeof(struct filsys)); 14326Sbill brelse(bp); 14426Sbill mount[0].m_bufp = cp; 14526Sbill mount[0].m_dev = rootdev; 14626Sbill fp = cp->b_un.b_filsys; 14726Sbill fp->s_flock = 0; 14826Sbill fp->s_ilock = 0; 14926Sbill fp->s_ronly = 0; 15026Sbill fp->s_lasti = 1; 15126Sbill fp->s_nbehind = 0; 15226Sbill /* on boot, read VAX TODR register (GMT 10 ms. 15326Sbill * clicks into current year) and set software time 15426Sbill * in 'int time' (GMT seconds since year YRREF) 15526Sbill */ 15626Sbill for (i = 0 , j = YRREF ; j < YRCURR ; j++) 15726Sbill i += (SECYR + (j%4?0:SECDAY)) ; 15826Sbill time = udiv(mfpr(TODR),100) + i ; 15926Sbill bootime = time; 16026Sbill } 16126Sbill 16226Sbill /* 16326Sbill * This is the set of buffers proper, whose heads 16426Sbill * were declared in buf.h. There can exist buffer 16526Sbill * headers not pointing here that are used purely 16626Sbill * as arguments to the I/O routines to describe 16726Sbill * I/O to be done-- e.g. swap headers swbuf[] for 16826Sbill * swapping. 16926Sbill */ 170108Sbill char buffers[NBUF][BSIZE]; 17126Sbill 17226Sbill /* 17326Sbill * Initialize the buffer I/O system by freeing 17426Sbill * all buffers and setting all device buffer lists to empty. 17526Sbill * 17626Sbill * SHOULD USE MEMALL HERE!!! 17726Sbill */ 17826Sbill binit() 17926Sbill { 18026Sbill register struct buf *bp; 18126Sbill register struct buf *dp; 18226Sbill register int i; 18326Sbill struct bdevsw *bdp; 184306Sbill struct swdevt *swp; 18526Sbill 18626Sbill bfreelist.b_forw = bfreelist.b_back = 18726Sbill bfreelist.av_forw = bfreelist.av_back = &bfreelist; 18826Sbill for (i=0; i<NBUF; i++) { 18926Sbill bp = &buf[i]; 19026Sbill bp->b_dev = NODEV; 19126Sbill bp->b_un.b_addr = buffers[i]; 19226Sbill bp->b_back = &bfreelist; 19326Sbill bp->b_forw = bfreelist.b_forw; 19426Sbill bfreelist.b_forw->b_back = bp; 19526Sbill bfreelist.b_forw = bp; 19626Sbill bp->b_flags = B_BUSY; 19726Sbill brelse(bp); 19826Sbill } 19926Sbill for (bdp = bdevsw; bdp->d_open; bdp++) { 20026Sbill dp = bdp->d_tab; 20126Sbill if(dp) { 20226Sbill dp->b_forw = dp; 20326Sbill dp->b_back = dp; 20426Sbill } 20526Sbill nblkdev++; 20626Sbill } 207306Sbill /* 208306Sbill * Count swap devices, and adjust total swap space available. 209306Sbill * Some of this space will not be available until a vswapon() 210306Sbill * system is issued, usually when the system goes multi-user. 211306Sbill */ 212306Sbill nswdev = 0; 213306Sbill for (swp = swdevt; swp->sw_dev; swp++) 214306Sbill nswdev++; 215306Sbill if (nswdev == 0) 216306Sbill panic("binit"); 217306Sbill nswap *= nswdev; 218306Sbill maxpgio *= nswdev; 219306Sbill swfree(0); 22026Sbill } 22126Sbill 22226Sbill /* 22326Sbill * Initialize linked list of free swap 22426Sbill * headers. These do not actually point 22526Sbill * to buffers, but rather to pages that 22626Sbill * are being swapped in and out. 22726Sbill */ 22826Sbill bswinit() 22926Sbill { 23026Sbill register int i; 23126Sbill 23226Sbill bswlist.av_forw = &swbuf[0]; 23326Sbill for (i=0; i<NSWBUF-1; i++) 23426Sbill swbuf[i].av_forw = &swbuf[i+1]; 23526Sbill swbuf[NSWBUF-1].av_forw = NULL; 23626Sbill } 237