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