1 /* init_main.c 4.39 82/10/10 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/kernel.h" 8 #include "../h/fs.h" 9 #include "../h/mount.h" 10 #include "../h/map.h" 11 #include "../h/proc.h" 12 #include "../h/inode.h" 13 #include "../h/seg.h" 14 #include "../h/conf.h" 15 #include "../h/buf.h" 16 #include "../h/pte.h" 17 #include "../h/vm.h" 18 #include "../h/cmap.h" 19 #include "../h/text.h" 20 #include "../h/clist.h" 21 #ifdef INET 22 #include "../h/protosw.h" 23 #endif 24 #include "../h/quota.h" 25 26 extern struct user u; /* have to declare it somewhere! */ 27 /* 28 * Initialization code. 29 * Called from cold start routine as 30 * soon as a stack and segmentation 31 * have been established. 32 * Functions: 33 * clear and free user core 34 * turn on clock 35 * hand craft 0th process 36 * call all initialization routines 37 * fork - process 0 to schedule 38 * - process 2 to page out 39 * - process 1 execute bootstrap 40 * 41 * loop at loc 13 (0xd) in user mode -- /etc/init 42 * cannot be executed. 43 */ 44 main(firstaddr) 45 { 46 register int i; 47 register struct proc *p; 48 struct fs *fs; 49 50 rqinit(); 51 #include "loop.h" 52 startup(firstaddr); 53 54 /* 55 * set up system process 0 (swapper) 56 */ 57 p = &proc[0]; 58 p->p_p0br = u.u_pcb.pcb_p0br; 59 p->p_szpt = 1; 60 p->p_addr = uaddr(p); 61 p->p_stat = SRUN; 62 p->p_flag |= SLOAD|SSYS; 63 p->p_nice = NZERO; 64 setredzone(p->p_addr, (caddr_t)&u); 65 u.u_procp = p; 66 u.u_cmask = CMASK; 67 for (i = 1; i < NGROUPS; i++) 68 u.u_groups[i] = -1; 69 for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) 70 u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = 71 RLIM_INFINITY; 72 u.u_rlimit[RLIMIT_STACK].rlim_cur = 512*1024; 73 u.u_rlimit[RLIMIT_STACK].rlim_max = ctob(MAXDSIZ); 74 u.u_rlimit[RLIMIT_DATA].rlim_max = 75 u.u_rlimit[RLIMIT_DATA].rlim_cur = ctob(MAXDSIZ); 76 p->p_maxrss = RLIM_INFINITY/NBPG; 77 #ifdef QUOTA 78 qtinit(); 79 p->p_quota = u.u_quota = getquota(0, 0, Q_NDQ); 80 #endif 81 clockstart(); 82 83 /* 84 * Initialize tables, protocols, and set up well-known inodes. 85 */ 86 mbinit(); 87 cinit(); /* needed by dmc-11 driver */ 88 #ifdef INET 89 #if NLOOP > 0 90 loattach(); /* XXX */ 91 #endif 92 ifinit(); 93 pfinit(); /* must follow interfaces */ 94 #endif 95 ihinit(); 96 bhinit(); 97 binit(); 98 bswinit(); 99 #ifdef GPROF 100 kmstartup(); 101 #endif 102 103 fs = mountfs(rootdev, 0, (struct inode *)0); 104 if (fs == 0) 105 panic("iinit"); 106 bcopy("/", fs->fs_fsmnt, 2); 107 108 /* initialize wall clock */ 109 clockinit(fs->fs_time); 110 boottime = time; 111 112 /* kick off timeout driven events by calling first time */ 113 roundrobin(); 114 schedcpu(); 115 schedpaging(); 116 117 /* set up the root file system */ 118 rootdir = iget(rootdev, fs, (ino_t)ROOTINO); 119 iunlock(rootdir); 120 u.u_cdir = iget(rootdev, fs, (ino_t)ROOTINO); 121 iunlock(u.u_cdir); 122 u.u_rdir = NULL; 123 124 u.u_dmap = zdmap; 125 u.u_smap = zdmap; 126 127 /* 128 * Set the scan rate and other parameters of the paging subsystem. 129 */ 130 setupclock(); 131 132 /* 133 * make page-out daemon (process 2) 134 * the daemon has ctopt(nswbuf*CLSIZE*KLMAX) pages of page 135 * table so that it can map dirty pages into 136 * its address space during asychronous pushes. 137 */ 138 mpid = 1; 139 proc[0].p_szpt = clrnd(ctopt(nswbuf*CLSIZE*KLMAX + UPAGES)); 140 proc[1].p_stat = SZOMB; /* force it to be in proc slot 2 */ 141 if (newproc(0)) { 142 proc[2].p_flag |= SLOAD|SSYS; 143 proc[2].p_dsize = u.u_dsize = nswbuf*CLSIZE*KLMAX; 144 pageout(); 145 } 146 147 /* 148 * make init process and 149 * enter scheduling loop 150 */ 151 152 mpid = 0; 153 proc[1].p_stat = 0; 154 proc[0].p_szpt = CLSIZE; 155 if (newproc(0)) { 156 expand(clrnd((int)btoc(szicode)), 0); 157 (void) swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap); 158 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 159 /* 160 * Return goes to loc. 0 of user init 161 * code just copied out. 162 */ 163 return; 164 } 165 #ifdef MUSH 166 /* 167 * start MUSH daemon 168 * pid == 3 169 */ 170 if (newproc(0)) { 171 expand(clrnd((int)btoc(szmcode)), 0); 172 (void) swpexpand(u.u_dsize, 0, &u.u_dmap, &u.u_smap); 173 (void) copyout((caddr_t)mcode, (caddr_t)0, (unsigned)szmcode); 174 /* 175 * Return goes to loc. 0 of user mush 176 * code just copied out. 177 */ 178 return; 179 } 180 #endif 181 proc[0].p_szpt = 1; 182 sched(); 183 } 184 185 /* 186 * Initialize hash links for buffers. 187 */ 188 bhinit() 189 { 190 register int i; 191 register struct bufhd *bp; 192 193 for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++) 194 bp->b_forw = bp->b_back = (struct buf *)bp; 195 } 196 197 /* 198 * Initialize the buffer I/O system by freeing 199 * all buffers and setting all device buffer lists to empty. 200 */ 201 binit() 202 { 203 register struct buf *bp; 204 register struct buf *dp; 205 register int i; 206 struct bdevsw *bdp; 207 struct swdevt *swp; 208 209 for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) { 210 dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp; 211 dp->b_flags = B_HEAD; 212 } 213 dp--; /* dp = &bfreelist[BQUEUES-1]; */ 214 for (i = 0; i < nbuf; i++) { 215 bp = &buf[i]; 216 bp->b_dev = NODEV; 217 bp->b_un.b_addr = buffers + i * MAXBSIZE; 218 bp->b_bcount = MAXBSIZE; 219 bp->b_back = dp; 220 bp->b_forw = dp->b_forw; 221 dp->b_forw->b_back = bp; 222 dp->b_forw = bp; 223 bp->b_flags = B_BUSY|B_INVAL; 224 brelse(bp); 225 } 226 for (bdp = bdevsw; bdp->d_open; bdp++) 227 nblkdev++; 228 /* 229 * Count swap devices, and adjust total swap space available. 230 * Some of this space will not be available until a vswapon() 231 * system is issued, usually when the system goes multi-user. 232 */ 233 nswdev = 0; 234 for (swp = swdevt; swp->sw_dev; swp++) 235 nswdev++; 236 if (nswdev == 0) 237 panic("binit"); 238 if (nswdev > 1) 239 nswap = (nswap/DMMAX)*DMMAX; 240 nswap *= nswdev; 241 maxpgio *= nswdev; 242 swfree(0); 243 } 244 245 /* 246 * Initialize linked list of free swap 247 * headers. These do not actually point 248 * to buffers, but rather to pages that 249 * are being swapped in and out. 250 */ 251 bswinit() 252 { 253 register int i; 254 register struct buf *sp = swbuf; 255 256 bswlist.av_forw = sp; 257 for (i=0; i<nswbuf-1; i++, sp++) 258 sp->av_forw = sp+1; 259 sp->av_forw = NULL; 260 } 261 262 /* 263 * Initialize clist by freeing all character blocks, then count 264 * number of character devices. (Once-only routine) 265 */ 266 cinit() 267 { 268 register int ccp; 269 register struct cblock *cp; 270 register struct cdevsw *cdp; 271 272 ccp = (int)cfree; 273 ccp = (ccp+CROUND) & ~CROUND; 274 for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) { 275 cp->c_next = cfreelist; 276 cfreelist = cp; 277 cfreecount += CBSIZE; 278 } 279 ccp = 0; 280 for(cdp = cdevsw; cdp->d_open; cdp++) 281 ccp++; 282 nchrdev = ccp; 283 } 284