Annotation of src/sys/kern/init_main.c, Revision 1.221.2.6
1.221.2.6! skrll 1: /* $NetBSD: init_main.c,v 1.221.2.5 2004/09/21 13:35:03 skrll Exp $ */
1.61 mycroft 2:
3: /*
4: * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: * (c) UNIX System Laboratories, Inc.
7: * All or some portions of this file are derived from material licensed
8: * to the University of California by American Telephone and Telegraph
9: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10: * the permission of UNIX System Laboratories, Inc.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
1.221.2.2 skrll 20: * 3. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)init_main.c 8.16 (Berkeley) 5/14/95
37: */
38:
39: /*
40: * Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
41: *
42: * Redistribution and use in source and binary forms, with or without
43: * modification, are permitted provided that the following conditions
44: * are met:
45: * 1. Redistributions of source code must retain the above copyright
46: * notice, this list of conditions and the following disclaimer.
47: * 2. Redistributions in binary form must reproduce the above copyright
48: * notice, this list of conditions and the following disclaimer in the
49: * documentation and/or other materials provided with the distribution.
1.61 mycroft 50: * 3. All advertising materials mentioning features or use of this software
51: * must display the following acknowledgement:
52: * This product includes software developed by the University of
53: * California, Berkeley and its contributors.
54: * 4. Neither the name of the University nor the names of its contributors
55: * may be used to endorse or promote products derived from this software
56: * without specific prior written permission.
57: *
58: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68: * SUCH DAMAGE.
69: *
1.118 fvdl 70: * @(#)init_main.c 8.16 (Berkeley) 5/14/95
1.61 mycroft 71: */
1.196 lukem 72:
73: #include <sys/cdefs.h>
1.221.2.6! skrll 74: __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.221.2.5 2004/09/21 13:35:03 skrll Exp $");
1.115 mrg 75:
1.117 thorpej 76: #include "fs_nfs.h"
1.123 thorpej 77: #include "opt_nfsserver.h"
1.221.2.2 skrll 78: #include "opt_ipsec.h"
1.134 tron 79: #include "opt_sysv.h"
1.158 simonb 80: #include "opt_maxuprc.h"
1.160 thorpej 81: #include "opt_multiprocessor.h"
1.198 jdolecek 82: #include "opt_pipe.h"
1.172 soren 83: #include "opt_syscall_debug.h"
1.201 christos 84: #include "opt_systrace.h"
1.217 christos 85: #include "opt_posix.h"
1.221.2.2 skrll 86: #include "opt_kcont.h"
1.61 mycroft 87:
1.221.2.2 skrll 88: #include "opencrypto.h"
1.106 explorer 89: #include "rnd.h"
90:
1.61 mycroft 91: #include <sys/param.h>
1.164 enami 92: #include <sys/acct.h>
1.61 mycroft 93: #include <sys/filedesc.h>
1.131 thorpej 94: #include <sys/file.h>
1.61 mycroft 95: #include <sys/errno.h>
1.162 thorpej 96: #include <sys/callout.h>
1.61 mycroft 97: #include <sys/kernel.h>
1.221.2.2 skrll 98: #include <sys/kcont.h>
1.61 mycroft 99: #include <sys/mount.h>
100: #include <sys/proc.h>
1.136 thorpej 101: #include <sys/kthread.h>
1.61 mycroft 102: #include <sys/resourcevar.h>
103: #include <sys/signalvar.h>
104: #include <sys/systm.h>
105: #include <sys/vnode.h>
1.87 thorpej 106: #include <sys/tty.h>
1.61 mycroft 107: #include <sys/conf.h>
1.95 thorpej 108: #include <sys/disklabel.h>
1.61 mycroft 109: #include <sys/buf.h>
110: #include <sys/device.h>
1.186 jdolecek 111: #include <sys/exec.h>
1.128 thorpej 112: #include <sys/socketvar.h>
1.61 mycroft 113: #include <sys/protosw.h>
114: #include <sys/reboot.h>
115: #include <sys/user.h>
1.176 thorpej 116: #include <sys/sysctl.h>
1.209 jdolecek 117: #include <sys/event.h>
1.221.2.2 skrll 118: #include <sys/mbuf.h>
119: #ifdef FAST_IPSEC
120: #include <netipsec/ipsec.h>
121: #endif
1.82 christos 122: #ifdef SYSVSHM
123: #include <sys/shm.h>
124: #endif
1.221.2.2 skrll 125: #ifdef SYSVSEM
1.82 christos 126: #include <sys/sem.h>
127: #endif
128: #ifdef SYSVMSG
129: #include <sys/msg.h>
130: #endif
1.217 christos 131: #ifdef P1003_1B_SEMAPHORE
132: #include <sys/ksem.h>
133: #endif
1.201 christos 134: #ifdef SYSTRACE
135: #include <sys/systrace.h>
136: #endif
1.82 christos 137: #include <sys/domain.h>
1.94 mouse 138: #include <sys/namei.h>
1.221.2.2 skrll 139: #if NOPENCRYPTO > 0
140: #include <opencrypto/cryptodev.h> /* XXX really the framework */
141: #endif
1.106 explorer 142: #if NRND > 0
1.103 explorer 143: #include <sys/rnd.h>
1.106 explorer 144: #endif
1.198 jdolecek 145: #ifndef PIPE_SOCKETPAIR
1.192 jdolecek 146: #include <sys/pipe.h>
147: #endif
1.210 thorpej 148: #ifdef LKM
149: #include <sys/lkm.h>
150: #endif
1.61 mycroft 151:
1.77 christos 152: #include <sys/syscall.h>
1.216 thorpej 153: #include <sys/sa.h>
1.68 cgd 154: #include <sys/syscallargs.h>
155:
1.61 mycroft 156: #include <ufs/ufs/quota.h>
157:
1.159 fvdl 158: #include <miscfs/genfs/genfs.h>
159: #include <miscfs/syncfs/syncfs.h>
160:
1.61 mycroft 161: #include <machine/cpu.h>
162:
1.114 mrg 163: #include <uvm/uvm.h>
164:
1.202 lukem 165: #include <dev/cons.h>
166:
1.81 christos 167: #include <net/if.h>
168: #include <net/raw_cb.h>
1.61 mycroft 169:
170: /* Components of the first process -- never freed. */
171: struct session session0;
172: struct pgrp pgrp0;
173: struct proc proc0;
1.216 thorpej 174: struct lwp lwp0;
1.61 mycroft 175: struct pcred cred0;
176: struct filedesc0 filedesc0;
1.148 thorpej 177: struct cwdinfo cwdi0;
1.61 mycroft 178: struct plimit limit0;
1.216 thorpej 179: struct pstats pstat0;
1.61 mycroft 180: struct vmspace vmspace0;
1.149 thorpej 181: struct sigacts sigacts0;
1.216 thorpej 182: #ifndef curlwp
183: struct lwp *curlwp = &lwp0;
1.133 pk 184: #endif
1.105 mycroft 185: struct proc *initproc;
1.61 mycroft 186:
1.214 abs 187: int nofile = NOFILE;
188: int maxuprc = MAXUPRC;
1.61 mycroft 189: int cmask = CMASK;
190: extern struct user *proc0paddr;
191:
192: struct vnode *rootvp, *swapdev_vp;
193: int boothowto;
1.156 thorpej 194: int cold = 1; /* still working on startup */
1.61 mycroft 195: struct timeval boottime;
1.221.2.2 skrll 196: time_t rootfstime; /* recorded root fs time, if known */
1.61 mycroft 197:
1.163 thorpej 198: __volatile int start_init_exec; /* semaphore for start_init() */
199:
1.221.2.5 skrll 200: static void check_console(struct lwp *l);
1.176 thorpej 201: static void start_init(void *);
202: void main(void);
1.76 cgd 203:
1.184 jdolecek 204: extern const struct emul emul_netbsd; /* defined in kern_exec.c */
1.77 christos 205:
1.61 mycroft 206: /*
207: * System startup; initialize the world, create process 0, mount root
208: * filesystem, and fork to create init and pagedaemon. Most of the
209: * hard work is done in the lower-level initialization routines including
210: * startup(), which does memory initialization and autoconfiguration.
211: */
1.81 christos 212: void
1.176 thorpej 213: main(void)
1.61 mycroft 214: {
1.216 thorpej 215: struct lwp *l;
1.144 thorpej 216: struct proc *p;
1.111 thorpej 217: struct pdevinit *pdev;
1.204 thorpej 218: int s, error;
219: u_int i;
1.182 he 220: rlim_t lim;
1.61 mycroft 221: extern struct pdevinit pdevinit[];
1.176 thorpej 222: extern void schedcpu(void *);
1.95 thorpej 223: #if defined(NFSSERVER) || defined(NFS)
1.176 thorpej 224: extern void nfs_init(void);
1.91 thorpej 225: #endif
1.175 jdolecek 226: #ifdef NVNODE_IMPLICIT
227: int usevnodes;
228: #endif
1.61 mycroft 229:
230: /*
1.216 thorpej 231: * Initialize the current LWP pointer (curlwp) before
1.61 mycroft 232: * any possible traps/probes to simplify trap processing.
233: */
1.216 thorpej 234: l = &lwp0;
235: curlwp = l;
236: l->l_cpu = curcpu();
237: l->l_proc = &proc0;
238: l->l_lid = 1;
1.221.2.2 skrll 239:
1.61 mycroft 240: /*
241: * Attempt to find console and initialize
242: * in case of early panic or other messages.
243: */
244: consinit();
1.141 cjs 245: printf("%s", copyright);
1.61 mycroft 246:
1.179 thorpej 247: KERNEL_LOCK_INIT();
248:
1.114 mrg 249: uvm_init();
1.127 thorpej 250:
1.145 thorpej 251: /* Do machine-dependent initialization. */
252: cpu_startup();
1.162 thorpej 253:
1.221.2.2 skrll 254: /* Initialise pools. */
255: link_pool_init();
256:
1.166 enami 257: /* Initialize callouts. */
258: callout_startup();
1.145 thorpej 259:
1.221.2.2 skrll 260: /* Initialize the buffer cache */
261: bufinit();
262:
1.127 thorpej 263: /*
264: * Initialize mbuf's. Do this now because we might attempt to
265: * allocate mbufs or mbuf clusters during autoconfiguration.
266: */
267: mbinit();
1.209 jdolecek 268:
1.128 thorpej 269: /* Initialize sockets. */
270: soinit();
1.127 thorpej 271:
1.221.2.2 skrll 272: #ifdef KCONT
273: /* Initialize kcont. */
274: kcont_init();
275: #endif
276:
1.156 thorpej 277: /*
1.212 thorpej 278: * The following things must be done before autoconfiguration.
1.156 thorpej 279: */
1.212 thorpej 280: evcnt_init(); /* initialize event counters */
1.156 thorpej 281: tty_init(); /* initialize tty list */
1.106 explorer 282: #if NRND > 0
1.156 thorpej 283: rnd_init(); /* initialize RNG */
1.106 explorer 284: #endif
1.221.2.2 skrll 285: #if NOPENCRYPTO > 0
286: /* Initialize crypto subsystem before configuring crypto hardware. */
287: (void)crypto_init();
288: #endif
1.176 thorpej 289: /* Initialize the sysctl subsystem. */
290: sysctl_init();
291:
1.221.2.2 skrll 292: /* Initialize process and pgrp structures. */
1.63 mycroft 293: procinit();
1.210 thorpej 294:
295: #ifdef LKM
296: /* Initialize the LKM system. */
297: lkm_init();
298: #endif
1.63 mycroft 299:
300: /*
1.61 mycroft 301: * Create process 0 (the swapper).
302: */
1.216 thorpej 303: p = &proc0;
1.218 dsl 304: proc0_insert(p, l, &pgrp0, &session0);
1.61 mycroft 305:
1.136 thorpej 306: /*
307: * Set P_NOCLDWAIT so that kernel threads are reparented to
308: * init(8) when they exit. init(8) can easily wait them out
309: * for us.
310: */
1.216 thorpej 311: p->p_flag = P_SYSTEM | P_NOCLDWAIT;
312: p->p_stat = SACTIVE;
1.61 mycroft 313: p->p_nice = NZERO;
1.77 christos 314: p->p_emul = &emul_netbsd;
1.187 mycroft 315: #ifdef __HAVE_SYSCALL_INTERN
316: (*p->p_emul->e_syscall_intern)(p);
317: #endif
1.146 gwr 318: strncpy(p->p_comm, "swapper", MAXCOMLEN);
1.165 thorpej 319:
1.216 thorpej 320: l->l_flag = L_INMEM;
321: l->l_stat = LSONPROC;
322: p->p_nrlwps = 1;
323:
324: callout_init(&l->l_tsleep_ch);
1.61 mycroft 325:
326: /* Create credentials. */
327: cred0.p_refcnt = 1;
328: p->p_cred = &cred0;
329: p->p_ucred = crget();
330: p->p_ucred->cr_ngroups = 1; /* group 0 */
331:
332: /* Create the file descriptor table. */
1.79 mycroft 333: p->p_fd = &filedesc0.fd_fd;
1.109 thorpej 334: fdinit1(&filedesc0);
1.61 mycroft 335:
1.148 thorpej 336: /* Create the CWD info. */
337: p->p_cwdi = &cwdi0;
338: cwdi0.cwdi_cmask = cmask;
339: cwdi0.cwdi_refcnt = 1;
1.221.2.2 skrll 340: simple_lock_init(&cwdi0.cwdi_slock);
1.148 thorpej 341:
1.61 mycroft 342: /* Create the limits structures. */
343: p->p_limit = &limit0;
1.221.2.2 skrll 344: simple_lock_init(&limit0.p_slock);
1.61 mycroft 345: for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
346: limit0.pl_rlimit[i].rlim_cur =
347: limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
1.140 christos 348:
349: limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
1.205 sommerfe 350: limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
1.214 abs 351: maxfiles < nofile ? maxfiles : nofile;
1.140 christos 352:
353: limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
354: limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
1.214 abs 355: maxproc < maxuprc ? maxproc : maxuprc;
1.140 christos 356:
1.182 he 357: lim = ptoa(uvmexp.free);
358: limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim;
359: limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim;
360: limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
1.157 bouyer 361: limit0.pl_corename = defcorename;
1.61 mycroft 362: limit0.p_refcnt = 1;
363:
1.120 thorpej 364: /*
365: * Initialize proc0's vmspace, which uses the kernel pmap.
366: * All kernel processes (which never have user space mappings)
367: * share proc0's vmspace, and thus, the kernel pmap.
368: */
369: uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
1.195 chs 370: trunc_page(VM_MAX_ADDRESS));
1.120 thorpej 371: p->p_vmspace = &vmspace0;
1.99 gwr 372:
1.216 thorpej 373: l->l_addr = proc0paddr; /* XXX */
1.61 mycroft 374:
1.216 thorpej 375: p->p_stats = &pstat0;
1.61 mycroft 376:
377: /*
1.63 mycroft 378: * Charge root for one process.
1.61 mycroft 379: */
380: (void)chgproccnt(0, 1);
381:
382: rqinit();
383:
384: /* Configure virtual memory system, set vm rlimits. */
1.114 mrg 385: uvm_init_limits(p);
1.61 mycroft 386:
387: /* Initialize the file systems. */
1.95 thorpej 388: #if defined(NFSSERVER) || defined(NFS)
1.91 thorpej 389: nfs_init(); /* initialize server/shared data */
390: #endif
1.194 matt 391: #ifdef NVNODE_IMPLICIT
392: /*
393: * If maximum number of vnodes in namei vnode cache is not explicitly
394: * defined in kernel config, adjust the number such as we use roughly
1.221.2.2 skrll 395: * 1.0% of memory for vnode cache (but not less than NVNODE vnodes).
1.194 matt 396: */
1.221.2.2 skrll 397: usevnodes = (ptoa((unsigned)physmem) / 100) / sizeof(struct vnode);
1.205 sommerfe 398: if (usevnodes > desiredvnodes)
1.194 matt 399: desiredvnodes = usevnodes;
400: #endif
1.61 mycroft 401: vfsinit();
402:
1.156 thorpej 403: /* Configure the system hardware. This will enable interrupts. */
404: configure();
1.61 mycroft 405:
1.185 chs 406: ubc_init(); /* must be after autoconfig */
407:
1.179 thorpej 408: /* Lock the kernel on behalf of proc0. */
1.216 thorpej 409: KERNEL_PROC_LOCK(l);
1.179 thorpej 410:
1.61 mycroft 411: #ifdef SYSVSHM
412: /* Initialize System V style shared memory. */
413: shminit();
414: #endif
415:
416: #ifdef SYSVSEM
417: /* Initialize System V style semaphores. */
418: seminit();
419: #endif
420:
421: #ifdef SYSVMSG
422: /* Initialize System V style message queues. */
423: msginit();
424: #endif
425:
1.217 christos 426: #ifdef P1003_1B_SEMAPHORE
427: /* Initialize posix semaphores */
428: ksem_init();
429: #endif
1.61 mycroft 430: /* Attach pseudo-devices. */
431: for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
432: (*pdev->pdev_attach)(pdev->pdev_count);
433:
1.221.2.2 skrll 434: #ifdef FAST_IPSEC
435: /* Attach network crypto subsystem */
436: ipsec_attach();
437: #endif
438:
1.61 mycroft 439: /*
440: * Initialize protocols. Block reception of incoming packets
441: * until everything is ready.
442: */
1.190 thorpej 443: s = splnet();
1.61 mycroft 444: ifinit();
445: domaininit();
1.200 itojun 446: if_attachdomain();
1.61 mycroft 447: splx(s);
448:
449: #ifdef GPROF
450: /* Initialize kernel profiling. */
451: kmstartup();
452: #endif
1.164 enami 453:
454: /* Initialize system accouting. */
455: acct_init();
1.61 mycroft 456:
1.201 christos 457: #ifdef SYSTRACE
458: systrace_init();
459: #endif
1.163 thorpej 460: /*
461: * Initialize signal-related data structures, and signal state
462: * for proc0.
463: */
464: signal_init();
465: p->p_sigacts = &sigacts0;
466: siginit(p);
467:
1.61 mycroft 468: /* Kick off timeout driven events by calling first time. */
469: schedcpu(NULL);
1.98 gwr 470:
1.163 thorpej 471: /*
472: * Create process 1 (init(8)). We do this now, as Unix has
473: * historically had init be process 1, and changing this would
474: * probably upset a lot of people.
475: *
476: * Note that process 1 won't immediately exec init(8), but will
477: * wait for us to inform it that the root file system has been
478: * mounted.
479: */
1.216 thorpej 480: if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
1.163 thorpej 481: panic("fork init");
482:
483: /*
484: * Create any kernel threads who's creation was deferred because
485: * initproc had not yet been created.
486: */
487: kthread_run_deferred_queue();
488:
489: /*
490: * Now that device driver threads have been created, wait for
491: * them to finish any deferred autoconfiguration. Note we don't
492: * need to lock this semaphore, since we haven't booted any
493: * secondary processors, yet.
494: */
495: while (config_pending)
496: (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0);
1.208 thorpej 497:
498: /*
499: * Finalize configuration now that all real devices have been
500: * found. This needs to be done before the root device is
501: * selected, since finalization may create the root device.
502: */
503: config_finalize();
1.163 thorpej 504:
505: /*
506: * Now that autoconfiguration has completed, we can determine
507: * the root and dump devices.
508: */
1.98 gwr 509: cpu_rootconf();
1.101 thorpej 510: cpu_dumpconf();
1.61 mycroft 511:
512: /* Mount the root file system. */
1.95 thorpej 513: do {
514: domountroothook();
515: if ((error = vfs_mountroot())) {
1.97 thorpej 516: printf("cannot mount root, error = %d\n", error);
1.95 thorpej 517: boothowto |= RB_ASKNAME;
518: setroot(root_device,
1.152 thorpej 519: (rootdev != NODEV) ? DISKPART(rootdev) : 0);
1.95 thorpej 520: }
521: } while (error != 0);
522: mountroothook_destroy();
523:
1.221.2.2 skrll 524: /*
525: * Initialise the time-of-day clock, passing the time recorded
526: * in the root filesystem (if any) for use by systems that
527: * don't have a non-volatile time-of-day device.
528: */
529: inittodr(rootfstime);
530:
1.206 matt 531: CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS;
532: CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++;
1.61 mycroft 533:
1.111 thorpej 534: /*
535: * Get the vnode for '/'. Set filedesc0.fd_fd.fd_cdir to
536: * reference it.
537: */
1.221.2.3 skrll 538: if (VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode))
1.61 mycroft 539: panic("cannot find root vnode");
1.148 thorpej 540: cwdi0.cwdi_cdir = rootvnode;
541: VREF(cwdi0.cwdi_cdir);
1.118 fvdl 542: VOP_UNLOCK(rootvnode, 0);
1.148 thorpej 543: cwdi0.cwdi_rdir = NULL;
1.163 thorpej 544:
545: /*
546: * Now that root is mounted, we can fixup initproc's CWD
547: * info. All other processes are kthreads, which merely
548: * share proc0's CWD info.
549: */
550: initproc->p_cwdi->cwdi_cdir = rootvnode;
551: VREF(initproc->p_cwdi->cwdi_cdir);
552: initproc->p_cwdi->cwdi_rdir = NULL;
1.61 mycroft 553:
554: /*
555: * Now can look at time, having had a chance to verify the time
556: * from the file system. Reset p->p_rtime as it may have been
557: * munched in mi_switch() after the time got set.
558: */
1.163 thorpej 559: proclist_lock_read();
1.178 thorpej 560: s = splsched();
1.221.2.2 skrll 561: LIST_FOREACH(p, &allproc, p_list) {
1.221.2.6! skrll 562: KASSERT((p->p_flag & P_MARKER) == 0);
1.171 thorpej 563: p->p_stats->p_start = mono_time = boottime = time;
1.221.2.2 skrll 564: LIST_FOREACH(l, &p->p_lwps, l_sibling) {
1.216 thorpej 565: if (l->l_cpu != NULL)
566: l->l_cpu->ci_schedstate.spc_runtime = time;
1.221.2.2 skrll 567: }
1.163 thorpej 568: p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
569: }
570: splx(s);
571: proclist_unlock_read();
1.61 mycroft 572:
1.163 thorpej 573: /* Create the pageout daemon kernel thread. */
574: uvm_swap_init();
1.177 thorpej 575: if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
1.135 thorpej 576: panic("fork pagedaemon");
1.61 mycroft 577:
1.163 thorpej 578: /* Create the filesystem syncer kernel thread. */
1.159 fvdl 579: if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
580: panic("fork syncer");
1.185 chs 581:
582: /* Create the aiodone daemon kernel thread. */
1.213 yamt 583: if (kthread_create1(uvm_aiodone_daemon, NULL, &uvm.aiodoned_proc,
584: "aiodoned"))
1.185 chs 585: panic("fork aiodoned");
1.137 thorpej 586:
1.160 thorpej 587: #if defined(MULTIPROCESSOR)
588: /* Boot the secondary processors. */
589: cpu_boot_secondary_processors();
590: #endif
1.186 jdolecek 591:
592: /* Initialize exec structures */
593: exec_init(1);
1.192 jdolecek 594:
1.163 thorpej 595: /*
596: * Okay, now we can let init(8) exec! It's off to userland!
597: */
598: start_init_exec = 1;
599: wakeup((void *)&start_init_exec);
600:
1.61 mycroft 601: /* The scheduler is an infinite loop. */
1.114 mrg 602: uvm_scheduler();
1.61 mycroft 603: /* NOTREACHED */
604: }
605:
1.221.2.2 skrll 606: void
607: setrootfstime(time_t t)
608: {
609: rootfstime = t;
610: }
611:
1.93 mouse 612: static void
1.221.2.5 skrll 613: check_console(struct lwp *l)
1.93 mouse 614: {
615: struct nameidata nd;
616: int error;
617:
1.221.2.5 skrll 618: NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", l);
1.93 mouse 619: error = namei(&nd);
1.96 cgd 620: if (error == 0)
621: vrele(nd.ni_vp);
622: else if (error == ENOENT)
623: printf("warning: no /dev/console\n");
1.93 mouse 624: else
1.96 cgd 625: printf("warning: lookup /dev/console: error %d\n", error);
1.93 mouse 626: }
627:
1.61 mycroft 628: /*
629: * List of paths to try when searching for "init".
630: */
1.176 thorpej 631: static const char *initpaths[] = {
1.61 mycroft 632: "/sbin/init",
633: "/sbin/oinit",
634: "/sbin/init.bak",
635: NULL,
636: };
637:
638: /*
639: * Start the initial user process; try exec'ing each pathname in "initpaths".
640: * The program is invoked with one argument containing the boot flags.
641: */
642: static void
1.176 thorpej 643: start_init(void *arg)
1.61 mycroft 644: {
1.216 thorpej 645: struct lwp *l = arg;
646: struct proc *p = l->l_proc;
1.130 eeh 647: vaddr_t addr;
1.78 mycroft 648: struct sys_execve_args /* {
1.108 mycroft 649: syscallarg(const char *) path;
1.92 cgd 650: syscallarg(char * const *) argp;
651: syscallarg(char * const *) envp;
1.68 cgd 652: } */ args;
653: int options, i, error;
654: register_t retval[2];
1.66 mycroft 655: char flags[4], *flagsp;
1.202 lukem 656: const char *path, *slash;
1.176 thorpej 657: char *ucp, **uap, *arg0, *arg1 = NULL;
1.202 lukem 658: char ipath[129];
659: int ipx, len;
1.61 mycroft 660:
1.76 cgd 661: /*
662: * Now in process 1.
663: */
1.146 gwr 664: strncpy(p->p_comm, "init", MAXCOMLEN);
1.163 thorpej 665:
666: /*
667: * Wait for main() to tell us that it's safe to exec.
668: */
669: while (start_init_exec == 0)
670: (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0);
1.93 mouse 671:
672: /*
673: * This is not the right way to do this. We really should
674: * hand-craft a descriptor onto /dev/console to hand to init,
675: * but that's a _lot_ more work, and the benefit from this easy
676: * hack makes up for the "good is the enemy of the best" effect.
677: */
1.221.2.5 skrll 678: check_console(l);
1.61 mycroft 679:
680: /*
681: * Need just enough stack to hold the faked-up "execve()" arguments.
682: */
1.211 chs 683: addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
1.205 sommerfe 684: if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
1.181 thorpej 685: NULL, UVM_UNKNOWN_OFFSET, 0,
1.114 mrg 686: UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
687: UVM_ADV_NORMAL,
1.189 chs 688: UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
1.114 mrg 689: panic("init: couldn't allocate argument space");
1.211 chs 690: p->p_vmspace->vm_maxsaddr = (caddr_t)STACK_MAX(addr, PAGE_SIZE);
1.61 mycroft 691:
1.202 lukem 692: ipx = 0;
693: while (1) {
694: if (boothowto & RB_ASKNAME) {
695: printf("init path");
696: if (initpaths[ipx])
697: printf(" (default %s)", initpaths[ipx]);
698: printf(": ");
699: len = cngetsn(ipath, sizeof(ipath)-1);
700: if (len == 0) {
701: if (initpaths[ipx])
702: path = initpaths[ipx++];
703: else
704: continue;
705: } else {
706: ipath[len] = '\0';
707: path = ipath;
708: }
709: } else {
710: if ((path = initpaths[ipx++]) == NULL)
711: break;
712: }
713:
1.211 chs 714: ucp = (char *)USRSTACK;
1.64 mycroft 715:
1.61 mycroft 716: /*
1.64 mycroft 717: * Construct the boot flag argument.
1.61 mycroft 718: */
1.66 mycroft 719: flagsp = flags;
720: *flagsp++ = '-';
1.61 mycroft 721: options = 0;
1.66 mycroft 722:
1.61 mycroft 723: if (boothowto & RB_SINGLE) {
1.64 mycroft 724: *flagsp++ = 's';
1.61 mycroft 725: options = 1;
726: }
727: #ifdef notyet
728: if (boothowto & RB_FASTBOOT) {
1.64 mycroft 729: *flagsp++ = 'f';
1.61 mycroft 730: options = 1;
731: }
732: #endif
1.64 mycroft 733:
734: /*
735: * Move out the flags (arg 1), if necessary.
736: */
737: if (options != 0) {
738: *flagsp++ = '\0';
739: i = flagsp - flags;
740: #ifdef DEBUG
1.90 christos 741: printf("init: copying out flags `%s' %d\n", flags, i);
1.64 mycroft 742: #endif
1.211 chs 743: arg1 = STACK_ALLOC(ucp, i);
744: ucp = STACK_MAX(arg1, i);
745: (void)copyout((caddr_t)flags, arg1, i);
1.64 mycroft 746: }
1.61 mycroft 747:
748: /*
749: * Move out the file name (also arg 0).
750: */
1.64 mycroft 751: i = strlen(path) + 1;
752: #ifdef DEBUG
1.90 christos 753: printf("init: copying out path `%s' %d\n", path, i);
1.202 lukem 754: #else
1.203 lukem 755: if (boothowto & RB_ASKNAME || path != initpaths[0])
1.202 lukem 756: printf("init: trying %s\n", path);
1.64 mycroft 757: #endif
1.211 chs 758: arg0 = STACK_ALLOC(ucp, i);
759: ucp = STACK_MAX(arg0, i);
760: (void)copyout((caddr_t)path, arg0, i);
1.61 mycroft 761:
762: /*
763: * Move out the arg pointers.
764: */
1.211 chs 765: ucp = (caddr_t)STACK_ALIGN(ucp, ALIGNBYTES);
766: uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
767: SCARG(&args, path) = arg0;
768: SCARG(&args, argp) = uap;
769: SCARG(&args, envp) = NULL;
1.142 mycroft 770: slash = strrchr(path, '/');
771: if (slash)
1.211 chs 772: (void)suword((caddr_t)uap++,
1.142 mycroft 773: (long)arg0 + (slash + 1 - path));
774: else
1.211 chs 775: (void)suword((caddr_t)uap++, (long)arg0);
776: if (options != 0)
777: (void)suword((caddr_t)uap++, (long)arg1);
778: (void)suword((caddr_t)uap++, 0); /* terminator */
1.61 mycroft 779:
780: /*
781: * Now try to exec the program. If can't for any reason
782: * other than it doesn't exist, complain.
783: */
1.221.2.5 skrll 784: error = sys_execve(l, &args, retval);
1.179 thorpej 785: if (error == 0 || error == EJUSTRETURN) {
1.216 thorpej 786: KERNEL_PROC_UNLOCK(l);
1.61 mycroft 787: return;
1.179 thorpej 788: }
1.202 lukem 789: printf("exec %s: error %d\n", path, error);
1.61 mycroft 790: }
1.90 christos 791: printf("init: not found\n");
1.61 mycroft 792: panic("no init");
793: }
CVSweb <webmaster@jp.NetBSD.org>