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