1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)init_main.c 7.57 (Berkeley) 12/01/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/filedesc.h> 12 #include <sys/kernel.h> 13 #include <sys/mount.h> 14 #include <sys/map.h> 15 #include <sys/proc.h> 16 #include <sys/resourcevar.h> 17 #include <sys/signalvar.h> 18 #include <sys/systm.h> 19 #include <sys/vnode.h> 20 #include <sys/conf.h> 21 #include <sys/buf.h> 22 #include <sys/clist.h> 23 #include <sys/protosw.h> 24 #include <sys/reboot.h> 25 #include <sys/user.h> 26 27 #include <ufs/ufs/quota.h> 28 29 #include <machine/cpu.h> 30 31 #include <vm/vm.h> 32 33 #ifdef HPFPLIB 34 char copyright[] = 35 "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; 36 #else 37 char copyright[] = 38 "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n"; 39 #endif 40 41 /* 42 * Components of process 0; 43 * never freed. 44 */ 45 struct session session0; 46 struct pgrp pgrp0; 47 struct proc proc0; 48 struct pcred cred0; 49 struct filedesc0 filedesc0; 50 struct plimit limit0; 51 struct vmspace vmspace0; 52 struct proc *curproc = &proc0; 53 struct proc *initproc, *pageproc; 54 55 int cmask = CMASK; 56 extern struct user *proc0paddr; 57 extern int (*mountroot)(); 58 59 struct vnode *rootvp, *swapdev_vp; 60 int boothowto; 61 struct timeval boottime; 62 struct timeval runtime; 63 64 /* 65 * System startup; initialize the world, create process 0, 66 * mount root filesystem, and fork to create init and pagedaemon. 67 * Most of the hard work is done in the lower-level initialization 68 * routines including startup(), which does memory initialization 69 * and autoconfiguration. 70 */ 71 main() 72 { 73 register int i; 74 register struct proc *p; 75 register struct filedesc0 *fdp; 76 int s, rval[2]; 77 extern void roundrobin __P((void *)); 78 extern void schedcpu __P((void *)); 79 80 /* 81 * Initialize curproc before any possible traps/probes 82 * to simplify trap processing. 83 */ 84 p = &proc0; 85 curproc = p; 86 /* 87 * Attempt to find console and initialize 88 * in case of early panic or other messages. 89 */ 90 consinit(); 91 printf(copyright); 92 93 vm_mem_init(); 94 kmeminit(); 95 cpu_startup(); 96 97 /* 98 * set up system process 0 (swapper) 99 */ 100 p = &proc0; 101 curproc = p; 102 103 allproc = (volatile struct proc *)p; 104 p->p_prev = (struct proc **)&allproc; 105 p->p_pgrp = &pgrp0; 106 pgrphash[0] = &pgrp0; 107 pgrp0.pg_mem = p; 108 pgrp0.pg_session = &session0; 109 session0.s_count = 1; 110 session0.s_leader = p; 111 112 p->p_flag = SLOAD|SSYS; 113 p->p_stat = SRUN; 114 p->p_nice = NZERO; 115 bcopy("swapper", p->p_comm, sizeof ("swapper")); 116 117 /* 118 * Setup credentials 119 */ 120 cred0.p_refcnt = 1; 121 p->p_cred = &cred0; 122 p->p_ucred = crget(); 123 p->p_ucred->cr_ngroups = 1; /* group 0 */ 124 125 /* 126 * Create the file descriptor table for process 0. 127 */ 128 fdp = &filedesc0; 129 p->p_fd = &fdp->fd_fd; 130 fdp->fd_fd.fd_refcnt = 1; 131 fdp->fd_fd.fd_cmask = cmask; 132 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 133 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 134 fdp->fd_fd.fd_nfiles = NDFILE; 135 136 /* 137 * Set initial limits 138 */ 139 p->p_limit = &limit0; 140 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 141 limit0.pl_rlimit[i].rlim_cur = 142 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 143 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 144 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 145 limit0.p_refcnt = 1; 146 147 /* 148 * Allocate a prototype map so we have something to fork 149 */ 150 p->p_vmspace = &vmspace0; 151 vmspace0.vm_refcnt = 1; 152 pmap_pinit(&vmspace0.vm_pmap); 153 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), 154 trunc_page(VM_MAX_ADDRESS), TRUE); 155 vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 156 p->p_addr = proc0paddr; /* XXX */ 157 158 /* 159 * We continue to place resource usage info 160 * and signal actions in the user struct so they're pageable. 161 */ 162 p->p_stats = &p->p_addr->u_stats; 163 p->p_sigacts = &p->p_addr->u_sigacts; 164 165 /* 166 * Initialize per uid information structure and charge 167 * root for one process. 168 */ 169 usrinfoinit(); 170 (void)chgproccnt(0, 1); 171 172 rqinit(); 173 174 /* 175 * configure virtual memory system, 176 * set vm rlimits 177 */ 178 vm_init_limits(p); 179 180 /* 181 * Initialize the file systems. 182 */ 183 vfsinit(); 184 185 /* 186 * Start real time and statistics clocks. 187 */ 188 initclocks(); 189 190 /* 191 * Initialize tables, protocols, and set up well-known inodes. 192 */ 193 mbinit(); 194 cinit(); 195 #ifdef SYSVSHM 196 shminit(); 197 #endif 198 #include "sl.h" 199 #if NSL > 0 200 slattach(); /* XXX */ 201 #endif 202 #include "loop.h" 203 #if NLOOP > 0 204 loattach(); /* XXX */ 205 #endif 206 /* 207 * Block reception of incoming packets 208 * until protocols have been initialized. 209 */ 210 s = splimp(); 211 ifinit(); 212 domaininit(); 213 splx(s); 214 215 #ifdef GPROF 216 kmstartup(); 217 #endif 218 219 /* kick off timeout driven events by calling first time */ 220 roundrobin(NULL); 221 schedcpu(NULL); 222 223 /* 224 * Set up the root file system and vnode. 225 */ 226 if ((*mountroot)()) 227 panic("cannot mount root"); 228 /* 229 * Get vnode for '/'. 230 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it. 231 */ 232 if (VFS_ROOT(rootfs, &rootdir)) 233 panic("cannot find root vnode"); 234 fdp->fd_fd.fd_cdir = rootdir; 235 VREF(fdp->fd_fd.fd_cdir); 236 VOP_UNLOCK(rootdir); 237 fdp->fd_fd.fd_rdir = NULL; 238 swapinit(); 239 240 /* 241 * Now can look at time, having had a chance to verify the time 242 * from the file system. Reset p->p_rtime as it may have been 243 * munched in swtch() after the time got set. 244 */ 245 p->p_stats->p_start = runtime = mono_time = boottime = time; 246 p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; 247 248 /* 249 * make init process 250 */ 251 siginit(p); 252 if (fork(p, NULL, rval)) 253 panic("fork init"); 254 if (rval[1]) { 255 extern int icode[]; /* user init code */ 256 extern int szicode; /* size of icode */ 257 static char initflags[] = "-sf"; 258 vm_offset_t addr; 259 char *ip; 260 261 /* 262 * Now in process 1. Set init flags into icode, get a minimal 263 * address space, copy out "icode", and return to it to do an 264 * exec of init. 265 */ 266 ip = initflags + 1; 267 if (boothowto&RB_SINGLE) 268 *ip++ = 's'; 269 #ifdef notyet 270 if (boothowto&RB_FASTBOOT) 271 *ip++ = 'f'; 272 #endif 273 if (ip == initflags + 1) 274 *ip++ = '-'; 275 *ip++ = '\0'; 276 277 addr = VM_MIN_ADDRESS; 278 initproc = p = curproc; 279 if (vm_allocate(&p->p_vmspace->vm_map, &addr, 280 round_page(szicode + sizeof(initflags)), FALSE) != 0 || 281 addr != VM_MIN_ADDRESS) 282 panic("init: couldn't allocate at zero"); 283 284 /* need just enough stack to exec from */ 285 addr = trunc_page(USRSTACK - PAGE_SIZE); 286 if (vm_allocate(&p->p_vmspace->vm_map, &addr, 287 PAGE_SIZE, FALSE) != KERN_SUCCESS) 288 panic("vm_allocate init stack"); 289 p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 290 (void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS, 291 (u_int)szicode); 292 (void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode), 293 sizeof(initflags)); 294 return; /* returns to icode */ 295 } 296 297 /* 298 * Start up pageout daemon (process 2). 299 */ 300 if (fork(p, NULL, rval)) 301 panic("fork pager"); 302 if (rval[1]) { 303 /* 304 * Now in process 2. 305 */ 306 p = curproc; 307 pageproc = p; 308 p->p_flag |= SLOAD|SSYS; /* XXX */ 309 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); 310 vm_pageout(); 311 /*NOTREACHED*/ 312 } 313 314 /* 315 * enter scheduling loop 316 */ 317 sched(); 318 } 319