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