1 /* init_main.c 3.9 07/12/80 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/filsys.h" 8 #include "../h/mount.h" 9 #include "../h/map.h" 10 #include "../h/proc.h" 11 #include "../h/inode.h" 12 #include "../h/seg.h" 13 #include "../h/conf.h" 14 #include "../h/buf.h" 15 #include "../h/mtpr.h" 16 #include "../h/pte.h" 17 #include "../h/clock.h" 18 #include "../h/vm.h" 19 #include "../h/cmap.h" 20 #include "../h/text.h" 21 #include "../h/limit.h" 22 23 /* 24 * Initialization code. 25 * Called from cold start routine as 26 * soon as a stack and segmentation 27 * have been established. 28 * Functions: 29 * clear and free user core 30 * turn on clock 31 * hand craft 0th process 32 * call all initialization routines 33 * fork - process 0 to schedule 34 * - process 2 to page out 35 * - process 1 execute bootstrap 36 * 37 * loop at loc 13 (0xd) in user mode -- /etc/init 38 * cannot be executed. 39 */ 40 main(firstaddr) 41 { 42 register int i; 43 44 cpusid = mfpr(SID); /* get system identification */ 45 #ifdef FASTVAX 46 rqinit(); 47 #endif 48 startup(firstaddr); 49 if (lotsfree == 0) 50 lotsfree = LOTSFREE; 51 52 /* 53 * set up system process 0 (swapper) 54 */ 55 56 proc[0].p_p0br = (struct pte *)mfpr(P0BR); 57 proc[0].p_szpt = 1; 58 proc[0].p_addr = uaddr(&proc[0]); 59 proc[0].p_stat = SRUN; 60 proc[0].p_flag |= SLOAD|SSYS; 61 proc[0].p_nice = NZERO; 62 u.u_procp = &proc[0]; 63 u.u_cmask = CMASK; 64 for (i = 1; i < sizeof(u.u_limit)/sizeof(u.u_limit[0]); i++) 65 u.u_limit[i] = INFINITY; 66 clkstart(); 67 68 /* 69 * Initialize devices and 70 * set up 'known' i-nodes 71 */ 72 73 ihinit(); 74 bhinit(); 75 cinit(); 76 binit(); 77 bswinit(); 78 iinit(); 79 rootdir = iget(rootdev, (ino_t)ROOTINO); 80 rootdir->i_flag &= ~ILOCK; 81 u.u_cdir = iget(rootdev, (ino_t)ROOTINO); 82 u.u_cdir->i_flag &= ~ILOCK; 83 u.u_rdir = NULL; 84 u.u_dmap = zdmap; 85 u.u_smap = zdmap; 86 87 /* 88 * make page-out daemon (process 2) 89 * the daemon has ctopt(NSWBUF*CLSIZE*KLMAX) pages of page 90 * table so that it can map dirty pages into 91 * its address space during asychronous pushes. 92 */ 93 94 mpid = 1; 95 proc[0].p_szpt = clrnd(ctopt(NSWBUF*CLSIZE*KLMAX + UPAGES)); 96 proc[1].p_stat = SZOMB; /* force it to be in proc slot 2 */ 97 if (newproc(0)) { 98 proc[2].p_flag |= SLOAD|SSYS; 99 proc[2].p_dsize = u.u_dsize = NSWBUF*CLSIZE*KLMAX; 100 pageout(); 101 } 102 103 /* 104 * make init process and 105 * enter scheduling loop 106 */ 107 108 mpid = 0; 109 proc[1].p_stat = 0; 110 proc[0].p_szpt = CLSIZE; 111 if (newproc(0)) { 112 expand(clrnd((int)btoc(szicode)), P0BR); 113 swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap); 114 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 115 /* 116 * Return goes to loc. 0 of user init 117 * code just copied out. 118 */ 119 return; 120 } 121 proc[0].p_szpt = 1; 122 sched(); 123 } 124 125 /* 126 * iinit is called once (from main) 127 * very early in initialization. 128 * It reads the root's super block 129 * and initializes the current date 130 * from the last modified date. 131 * 132 * panic: iinit -- cannot read the super 133 * block. Usually because of an IO error. 134 */ 135 iinit() 136 { 137 register struct buf *cp, *bp; 138 register struct filsys *fp; 139 register unsigned i, j; 140 141 (*bdevsw[major(rootdev)].d_open)(rootdev, 1); 142 bp = bread(rootdev, SUPERB); 143 cp = geteblk(); 144 if(u.u_error) 145 panic("iinit"); 146 bcopy(bp->b_un.b_addr, cp->b_un.b_addr, sizeof(struct filsys)); 147 brelse(bp); 148 mount[0].m_bufp = cp; 149 mount[0].m_dev = rootdev; 150 fp = cp->b_un.b_filsys; 151 fp->s_flock = 0; 152 fp->s_ilock = 0; 153 fp->s_ronly = 0; 154 fp->s_lasti = 1; 155 fp->s_nbehind = 0; 156 /* on boot, read VAX TODR register (GMT 10 ms. 157 * clicks into current year) and set software time 158 * in 'int time' (GMT seconds since year YRREF) 159 */ 160 for (i = 0 , j = YRREF ; j < YRCURR ; j++) 161 i += (SECYR + (j%4?0:SECDAY)) ; 162 time = udiv(mfpr(TODR),100) + i ; 163 bootime = time; 164 } 165 166 /* 167 * This is the set of buffers proper, whose heads 168 * were declared in buf.h. There can exist buffer 169 * headers not pointing here that are used purely 170 * as arguments to the I/O routines to describe 171 * I/O to be done-- e.g. swap headers swbuf[] for 172 * swapping. 173 */ 174 char buffers[NBUF][BSIZE]; 175 176 /* 177 * Initialize the buffer I/O system by freeing 178 * all buffers and setting all device buffer lists to empty. 179 * 180 * SHOULD USE MEMALL HERE!!! 181 */ 182 binit() 183 { 184 register struct buf *bp; 185 register struct buf *dp; 186 register int i; 187 struct bdevsw *bdp; 188 struct swdevt *swp; 189 190 bfreelist.b_forw = bfreelist.b_back = 191 bfreelist.av_forw = bfreelist.av_back = &bfreelist; 192 for (i=0; i<NBUF; i++) { 193 bp = &buf[i]; 194 bp->b_dev = NODEV; 195 bp->b_un.b_addr = buffers[i]; 196 bp->b_back = &bfreelist; 197 bp->b_forw = bfreelist.b_forw; 198 bfreelist.b_forw->b_back = bp; 199 bfreelist.b_forw = bp; 200 bp->b_flags = B_BUSY; 201 brelse(bp); 202 } 203 for (bdp = bdevsw; bdp->d_open; bdp++) { 204 dp = bdp->d_tab; 205 if(dp) { 206 dp->b_forw = dp; 207 dp->b_back = dp; 208 } 209 nblkdev++; 210 } 211 /* 212 * Count swap devices, and adjust total swap space available. 213 * Some of this space will not be available until a vswapon() 214 * system is issued, usually when the system goes multi-user. 215 */ 216 nswdev = 0; 217 for (swp = swdevt; swp->sw_dev; swp++) 218 nswdev++; 219 if (nswdev == 0) 220 panic("binit"); 221 nswap *= nswdev; 222 maxpgio *= nswdev; 223 swfree(0); 224 } 225 226 /* 227 * Initialize linked list of free swap 228 * headers. These do not actually point 229 * to buffers, but rather to pages that 230 * are being swapped in and out. 231 */ 232 bswinit() 233 { 234 register int i; 235 236 bswlist.av_forw = &swbuf[0]; 237 for (i=0; i<NSWBUF-1; i++) 238 swbuf[i].av_forw = &swbuf[i+1]; 239 swbuf[NSWBUF-1].av_forw = NULL; 240 } 241