1 /* $NetBSD: init_main.c,v 1.312 2007/08/04 11:03:00 ad Exp $ */ 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. 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. 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 * 70 * @(#)init_main.c 8.16 (Berkeley) 5/14/95 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.312 2007/08/04 11:03:00 ad Exp $"); 75 76 #include "opt_ipsec.h" 77 #include "opt_multiprocessor.h" 78 #include "opt_ntp.h" 79 #include "opt_pipe.h" 80 #include "opt_posix.h" 81 #include "opt_syscall_debug.h" 82 #include "opt_sysv.h" 83 #include "opt_systrace.h" 84 #include "opt_fileassoc.h" 85 #include "opt_ktrace.h" 86 #include "opt_pax.h" 87 88 #include "sysmon_taskq.h" 89 #include "rnd.h" 90 #include "sysmon_envsys.h" 91 #include "sysmon_power.h" 92 #include "veriexec.h" 93 94 #include <sys/param.h> 95 #include <sys/acct.h> 96 #include <sys/filedesc.h> 97 #include <sys/file.h> 98 #include <sys/errno.h> 99 #include <sys/callout.h> 100 #include <sys/cpu.h> 101 #include <sys/kernel.h> 102 #include <sys/kmem.h> 103 #include <sys/mount.h> 104 #include <sys/proc.h> 105 #include <sys/kthread.h> 106 #include <sys/resourcevar.h> 107 #include <sys/signalvar.h> 108 #include <sys/systm.h> 109 #include <sys/vnode.h> 110 #include <sys/fstrans.h> 111 #include <sys/tty.h> 112 #include <sys/conf.h> 113 #include <sys/disklabel.h> 114 #include <sys/buf.h> 115 #include <sys/device.h> 116 #include <sys/exec.h> 117 #include <sys/socketvar.h> 118 #include <sys/protosw.h> 119 #include <sys/reboot.h> 120 #include <sys/user.h> 121 #include <sys/sysctl.h> 122 #include <sys/event.h> 123 #include <sys/mbuf.h> 124 #include <sys/sched.h> 125 #include <sys/sleepq.h> 126 #include <sys/iostat.h> 127 #include <sys/vmem.h> 128 #include <sys/uuid.h> 129 #include <sys/extent.h> 130 #include <sys/disk.h> 131 #ifdef FAST_IPSEC 132 #include <netipsec/ipsec.h> 133 #endif 134 #ifdef SYSVSHM 135 #include <sys/shm.h> 136 #endif 137 #ifdef SYSVSEM 138 #include <sys/sem.h> 139 #endif 140 #ifdef SYSVMSG 141 #include <sys/msg.h> 142 #endif 143 #ifdef SYSTRACE 144 #include <sys/systrace.h> 145 #endif 146 #ifdef P1003_1B_SEMAPHORE 147 #include <sys/ksem.h> 148 #endif 149 #include <sys/domain.h> 150 #include <sys/namei.h> 151 #if NRND > 0 152 #include <sys/rnd.h> 153 #endif 154 #include <sys/pipe.h> 155 #ifdef LKM 156 #include <sys/lkm.h> 157 #endif 158 #if NVERIEXEC > 0 159 #include <sys/verified_exec.h> 160 #endif /* NVERIEXEC > 0 */ 161 #ifdef KTRACE 162 #include <sys/ktrace.h> 163 #endif 164 #include <sys/debug.h> 165 #include <sys/kauth.h> 166 #include <net80211/ieee80211_netbsd.h> 167 168 #include <sys/syscall.h> 169 #include <sys/syscallargs.h> 170 171 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) 172 #include <sys/pax.h> 173 #endif /* PAX_MPROTECT || PAX_SEGVGUARD */ 174 #include <ufs/ufs/quota.h> 175 176 #include <miscfs/genfs/genfs.h> 177 #include <miscfs/syncfs/syncfs.h> 178 179 #include <machine/cpu.h> 180 181 #include <uvm/uvm.h> 182 183 #if NSYSMON_TASKQ > 0 184 #include <dev/sysmon/sysmon_taskq.h> 185 #endif 186 187 #include <dev/cons.h> 188 189 #if NSYSMON_ENVSYS > 0 || NSYSMON_POWER > 0 190 #include <dev/sysmon/sysmonvar.h> 191 #endif 192 193 #include <net/if.h> 194 #include <net/raw_cb.h> 195 196 #include <secmodel/secmodel.h> 197 198 extern struct proc proc0; 199 extern struct lwp lwp0; 200 extern struct cwdinfo cwdi0; 201 extern time_t rootfstime; 202 203 #ifndef curlwp 204 struct lwp *curlwp = &lwp0; 205 #endif 206 struct proc *initproc; 207 208 struct vnode *rootvp, *swapdev_vp; 209 int boothowto; 210 int cold = 1; /* still working on startup */ 211 struct timeval boottime; /* time at system startup - will only follow settime deltas */ 212 int ncpu = 0; /* number of CPUs configured, assume 1 */ 213 214 volatile int start_init_exec; /* semaphore for start_init() */ 215 216 static void check_console(struct lwp *l); 217 static void start_init(void *); 218 void main(void); 219 220 #if defined(__SSP__) || defined(__SSP_ALL__) 221 long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 222 void __stack_chk_fail(void); 223 224 void 225 __stack_chk_fail(void) 226 { 227 panic("stack overflow detected; terminated"); 228 } 229 #endif 230 231 void __secmodel_none(void); 232 __weak_alias(secmodel_start,__secmodel_none); 233 void 234 __secmodel_none(void) 235 { 236 return; 237 } 238 239 /* 240 * System startup; initialize the world, create process 0, mount root 241 * filesystem, and fork to create init and pagedaemon. Most of the 242 * hard work is done in the lower-level initialization routines including 243 * startup(), which does memory initialization and autoconfiguration. 244 */ 245 void 246 main(void) 247 { 248 #ifdef __HAVE_TIMECOUNTER 249 struct timeval time; 250 #endif 251 struct lwp *l; 252 struct proc *p; 253 struct pdevinit *pdev; 254 int s, error; 255 extern struct pdevinit pdevinit[]; 256 #ifdef NVNODE_IMPLICIT 257 int usevnodes; 258 #endif 259 CPU_INFO_ITERATOR cii; 260 struct cpu_info *ci; 261 262 /* 263 * Initialize the current LWP pointer (curlwp) before 264 * any possible traps/probes to simplify trap processing. 265 */ 266 l = &lwp0; 267 curlwp = l; 268 l->l_cpu = curcpu(); 269 l->l_proc = &proc0; 270 l->l_lid = 1; 271 272 /* 273 * Attempt to find console and initialize 274 * in case of early panic or other messages. 275 */ 276 consinit(); 277 278 KERNEL_LOCK_INIT(); 279 280 uvm_init(); 281 282 #ifdef DEBUG 283 debug_init(); 284 #endif 285 286 kmem_init(); 287 288 /* Initialize the extent manager. */ 289 extent_init(); 290 291 /* Do machine-dependent initialization. */ 292 cpu_startup(); 293 294 /* Initialize callouts, part 1. */ 295 callout_startup(); 296 297 /* 298 * Initialize the kernel authorization subsystem and start the 299 * default security model, if any. We need to do this early 300 * enough so that subsystems relying on any of the aforementioned 301 * can work properly. Since the security model may dictate the 302 * credential inheritance policy, it is needed at least before 303 * any process is created, specifically proc0. 304 */ 305 kauth_init(); 306 secmodel_start(); 307 308 /* Initialize the buffer cache */ 309 bufinit(); 310 311 /* 312 * Initialize mbuf's. Do this now because we might attempt to 313 * allocate mbufs or mbuf clusters during autoconfiguration. 314 */ 315 mbinit(); 316 317 /* Initialize sockets. */ 318 soinit(); 319 320 /* 321 * The following things must be done before autoconfiguration. 322 */ 323 evcnt_init(); /* initialize event counters */ 324 #if NRND > 0 325 rnd_init(); /* initialize RNG */ 326 #endif 327 328 /* Initialize process and pgrp structures. */ 329 procinit(); 330 lwpinit(); 331 332 /* Initialize signal-related data structures. */ 333 signal_init(); 334 335 /* Create process 0 (the swapper). */ 336 proc0_init(); 337 338 /* Initialize the UID hash table. */ 339 uid_init(); 340 341 /* Charge root for one process. */ 342 (void)chgproccnt(0, 1); 343 344 /* Initialize the run queues, turnstiles and sleep queues. */ 345 mutex_init(&cpu_lock, MUTEX_DEFAULT, IPL_NONE); 346 sched_rqinit(); 347 turnstile_init(); 348 sleeptab_init(&sleeptab); 349 350 /* MI initialization of the boot cpu */ 351 error = mi_cpu_attach(curcpu()); 352 KASSERT(error == 0); 353 354 /* Initialize the sysctl subsystem. */ 355 sysctl_init(); 356 357 /* Initialize I/O statistics. */ 358 iostat_init(); 359 360 /* Initialize the file systems. */ 361 #ifdef NVNODE_IMPLICIT 362 /* 363 * If maximum number of vnodes in namei vnode cache is not explicitly 364 * defined in kernel config, adjust the number such as we use roughly 365 * 1.0% of memory for vnode cache (but not less than NVNODE vnodes). 366 */ 367 usevnodes = (ptoa((unsigned)physmem) / 100) / sizeof(struct vnode); 368 if (usevnodes > desiredvnodes) 369 desiredvnodes = usevnodes; 370 #endif 371 vfsinit(); 372 373 /* Initialize fstrans. */ 374 fstrans_init(); 375 376 /* Initialize the select()/poll() system calls. */ 377 selsysinit(); 378 379 /* Initialize asynchronous I/O. */ 380 aio_sysinit(); 381 382 #if NSYSMON_TASKQ > 0 383 sysmon_task_queue_preinit(); 384 #endif 385 386 #if NSYSMON_ENVSYS > 0 387 sysmon_envsys_init(); 388 #endif 389 390 #if NSYSMON_POWER > 0 391 sysmon_power_init(); 392 #endif 393 #ifdef __HAVE_TIMECOUNTER 394 inittimecounter(); 395 ntp_init(); 396 #endif /* __HAVE_TIMECOUNTER */ 397 398 /* Initialize the device switch tables. */ 399 devsw_init(); 400 401 /* Initialize the disk wedge subsystem. */ 402 dkwedge_init(); 403 404 /* Configure the system hardware. This will enable interrupts. */ 405 configure(); 406 407 #if defined(__SSP__) || defined(__SSP_ALL__) 408 { 409 #ifdef DIAGNOSTIC 410 printf("Initializing SSP:"); 411 #endif 412 /* 413 * We initialize ssp here carefully: 414 * 1. after we got some entropy 415 * 2. without calling a function 416 */ 417 size_t i; 418 long guard[__arraycount(__stack_chk_guard)]; 419 420 arc4randbytes(guard, sizeof(guard)); 421 for (i = 0; i < __arraycount(guard); i++) 422 __stack_chk_guard[i] = guard[i]; 423 #ifdef DIAGNOSTIC 424 for (i = 0; i < __arraycount(guard); i++) 425 printf("%lx ", guard[i]); 426 printf("\n"); 427 #endif 428 } 429 #endif 430 ubc_init(); /* must be after autoconfig */ 431 432 /* Lock the kernel on behalf of proc0. */ 433 KERNEL_LOCK(1, l); 434 435 #ifdef SYSTRACE 436 systrace_init(); 437 #endif 438 439 #ifdef SYSVSHM 440 /* Initialize System V style shared memory. */ 441 shminit(); 442 #endif 443 444 #ifdef SYSVSEM 445 /* Initialize System V style semaphores. */ 446 seminit(); 447 #endif 448 449 #ifdef SYSVMSG 450 /* Initialize System V style message queues. */ 451 msginit(); 452 #endif 453 454 #ifdef P1003_1B_SEMAPHORE 455 /* Initialize posix semaphores */ 456 ksem_init(); 457 #endif 458 459 #if NVERIEXEC > 0 460 /* 461 * Initialise the Veriexec subsystem. 462 */ 463 veriexec_init(); 464 #endif /* NVERIEXEC > 0 */ 465 466 #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) 467 pax_init(); 468 #endif /* PAX_MPROTECT || PAX_SEGVGUARD */ 469 470 /* Attach pseudo-devices. */ 471 for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++) 472 (*pdev->pdev_attach)(pdev->pdev_count); 473 474 #ifdef FAST_IPSEC 475 /* Attach network crypto subsystem */ 476 ipsec_attach(); 477 #endif 478 479 /* 480 * Initialize protocols. Block reception of incoming packets 481 * until everything is ready. 482 */ 483 s = splnet(); 484 ifinit(); 485 domaininit(); 486 if_attachdomain(); 487 splx(s); 488 489 #ifdef GPROF 490 /* Initialize kernel profiling. */ 491 kmstartup(); 492 #endif 493 494 /* Initialize system accouting. */ 495 acct_init(); 496 497 #ifndef PIPE_SOCKETPAIR 498 /* Initialize pipes. */ 499 pipe_init(); 500 #endif 501 502 /* Setup the scheduler */ 503 sched_init(); 504 505 #ifdef KTRACE 506 /* Initialize ktrace. */ 507 ktrinit(); 508 #endif 509 510 /* Initialize the UUID system calls. */ 511 uuid_init(); 512 513 /* 514 * Create process 1 (init(8)). We do this now, as Unix has 515 * historically had init be process 1, and changing this would 516 * probably upset a lot of people. 517 * 518 * Note that process 1 won't immediately exec init(8), but will 519 * wait for us to inform it that the root file system has been 520 * mounted. 521 */ 522 if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc)) 523 panic("fork init"); 524 525 /* 526 * Now that device driver threads have been created, wait for 527 * them to finish any deferred autoconfiguration. Note we don't 528 * need to lock this semaphore, since we haven't booted any 529 * secondary processors, yet. 530 */ 531 while (config_pending) 532 (void) tsleep(&config_pending, PWAIT, "cfpend", 0); 533 534 /* 535 * Finalize configuration now that all real devices have been 536 * found. This needs to be done before the root device is 537 * selected, since finalization may create the root device. 538 */ 539 config_finalize(); 540 541 /* 542 * Now that autoconfiguration has completed, we can determine 543 * the root and dump devices. 544 */ 545 cpu_rootconf(); 546 cpu_dumpconf(); 547 548 /* Mount the root file system. */ 549 do { 550 domountroothook(); 551 if ((error = vfs_mountroot())) { 552 printf("cannot mount root, error = %d\n", error); 553 boothowto |= RB_ASKNAME; 554 setroot(root_device, 555 (rootdev != NODEV) ? DISKPART(rootdev) : 0); 556 } 557 } while (error != 0); 558 mountroothook_destroy(); 559 560 /* 561 * Initialise the time-of-day clock, passing the time recorded 562 * in the root filesystem (if any) for use by systems that 563 * don't have a non-volatile time-of-day device. 564 */ 565 inittodr(rootfstime); 566 567 CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS; 568 CIRCLEQ_FIRST(&mountlist)->mnt_op->vfs_refcount++; 569 570 /* 571 * Get the vnode for '/'. Set filedesc0.fd_fd.fd_cdir to 572 * reference it. 573 */ 574 error = VFS_ROOT(CIRCLEQ_FIRST(&mountlist), &rootvnode); 575 if (error) 576 panic("cannot find root vnode, error=%d", error); 577 cwdi0.cwdi_cdir = rootvnode; 578 VREF(cwdi0.cwdi_cdir); 579 VOP_UNLOCK(rootvnode, 0); 580 cwdi0.cwdi_rdir = NULL; 581 582 /* 583 * Now that root is mounted, we can fixup initproc's CWD 584 * info. All other processes are kthreads, which merely 585 * share proc0's CWD info. 586 */ 587 initproc->p_cwdi->cwdi_cdir = rootvnode; 588 VREF(initproc->p_cwdi->cwdi_cdir); 589 initproc->p_cwdi->cwdi_rdir = NULL; 590 591 /* 592 * Now can look at time, having had a chance to verify the time 593 * from the file system. Reset l->l_rtime as it may have been 594 * munched in mi_switch() after the time got set. 595 */ 596 #ifdef __HAVE_TIMECOUNTER 597 getmicrotime(&time); 598 #else 599 mono_time = time; 600 #endif 601 boottime = time; 602 mutex_enter(&proclist_lock); 603 LIST_FOREACH(p, &allproc, p_list) { 604 KASSERT((p->p_flag & PK_MARKER) == 0); 605 mutex_enter(&p->p_smutex); 606 p->p_stats->p_start = time; 607 LIST_FOREACH(l, &p->p_lwps, l_sibling) { 608 lwp_lock(l); 609 l->l_cpu->ci_schedstate.spc_runtime = time; 610 l->l_rtime.tv_sec = l->l_rtime.tv_usec = 0; 611 lwp_unlock(l); 612 } 613 mutex_exit(&p->p_smutex); 614 } 615 mutex_exit(&proclist_lock); 616 617 for (CPU_INFO_FOREACH(cii, ci)) { 618 ci->ci_schedstate.spc_lastmod = time_second; 619 } 620 621 /* Create the pageout daemon kernel thread. */ 622 uvm_swap_init(); 623 if (kthread_create(PVM, 0, NULL, uvm_pageout, 624 NULL, NULL, "pgdaemon")) 625 panic("fork pagedaemon"); 626 627 /* Create the filesystem syncer kernel thread. */ 628 if (kthread_create(PINOD, 0, NULL, sched_sync, NULL, NULL, "ioflush")) 629 panic("fork syncer"); 630 631 /* Create the aiodone daemon kernel thread. */ 632 if (workqueue_create(&uvm.aiodone_queue, "aiodoned", 633 uvm_aiodone_worker, NULL, PVM, IPL_BIO, 0)) 634 panic("fork aiodoned"); 635 636 vmem_rehash_start(); 637 638 #if defined(MULTIPROCESSOR) 639 /* Boot the secondary processors. */ 640 cpu_boot_secondary_processors(); 641 #endif 642 643 /* Initialize exec structures */ 644 exec_init(1); 645 646 /* 647 * Okay, now we can let init(8) exec! It's off to userland! 648 */ 649 start_init_exec = 1; 650 wakeup(&start_init_exec); 651 652 /* The scheduler is an infinite loop. */ 653 uvm_scheduler(); 654 /* NOTREACHED */ 655 } 656 657 static void 658 check_console(struct lwp *l) 659 { 660 struct nameidata nd; 661 int error; 662 663 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", l); 664 error = namei(&nd); 665 if (error == 0) 666 vrele(nd.ni_vp); 667 else if (error == ENOENT) 668 printf("warning: no /dev/console\n"); 669 else 670 printf("warning: lookup /dev/console: error %d\n", error); 671 } 672 673 /* 674 * List of paths to try when searching for "init". 675 */ 676 static const char *initpaths[] = { 677 "/sbin/init", 678 "/sbin/oinit", 679 "/sbin/init.bak", 680 NULL, 681 }; 682 683 /* 684 * Start the initial user process; try exec'ing each pathname in "initpaths". 685 * The program is invoked with one argument containing the boot flags. 686 */ 687 static void 688 start_init(void *arg) 689 { 690 struct lwp *l = arg; 691 struct proc *p = l->l_proc; 692 vaddr_t addr; 693 struct sys_execve_args /* { 694 syscallarg(const char *) path; 695 syscallarg(char * const *) argp; 696 syscallarg(char * const *) envp; 697 } */ args; 698 int options, i, error; 699 register_t retval[2]; 700 char flags[4], *flagsp; 701 const char *path, *slash; 702 char *ucp, **uap, *arg0, *arg1 = NULL; 703 char ipath[129]; 704 int ipx, len; 705 706 /* 707 * Now in process 1. 708 */ 709 strncpy(p->p_comm, "init", MAXCOMLEN); 710 711 /* 712 * Wait for main() to tell us that it's safe to exec. 713 */ 714 while (start_init_exec == 0) 715 (void) tsleep(&start_init_exec, PWAIT, "initexec", 0); 716 717 /* 718 * This is not the right way to do this. We really should 719 * hand-craft a descriptor onto /dev/console to hand to init, 720 * but that's a _lot_ more work, and the benefit from this easy 721 * hack makes up for the "good is the enemy of the best" effect. 722 */ 723 check_console(l); 724 725 /* 726 * Need just enough stack to hold the faked-up "execve()" arguments. 727 */ 728 addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE); 729 if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE, 730 NULL, UVM_UNKNOWN_OFFSET, 0, 731 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY, 732 UVM_ADV_NORMAL, 733 UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0) 734 panic("init: couldn't allocate argument space"); 735 p->p_vmspace->vm_maxsaddr = (void *)STACK_MAX(addr, PAGE_SIZE); 736 737 ipx = 0; 738 while (1) { 739 if (boothowto & RB_ASKNAME) { 740 printf("init path"); 741 if (initpaths[ipx]) 742 printf(" (default %s)", initpaths[ipx]); 743 printf(": "); 744 len = cngetsn(ipath, sizeof(ipath)-1); 745 if (len == 0) { 746 if (initpaths[ipx]) 747 path = initpaths[ipx++]; 748 else 749 continue; 750 } else { 751 ipath[len] = '\0'; 752 path = ipath; 753 } 754 } else { 755 if ((path = initpaths[ipx++]) == NULL) 756 break; 757 } 758 759 ucp = (char *)USRSTACK; 760 761 /* 762 * Construct the boot flag argument. 763 */ 764 flagsp = flags; 765 *flagsp++ = '-'; 766 options = 0; 767 768 if (boothowto & RB_SINGLE) { 769 *flagsp++ = 's'; 770 options = 1; 771 } 772 #ifdef notyet 773 if (boothowto & RB_FASTBOOT) { 774 *flagsp++ = 'f'; 775 options = 1; 776 } 777 #endif 778 779 /* 780 * Move out the flags (arg 1), if necessary. 781 */ 782 if (options != 0) { 783 *flagsp++ = '\0'; 784 i = flagsp - flags; 785 #ifdef DEBUG 786 printf("init: copying out flags `%s' %d\n", flags, i); 787 #endif 788 arg1 = STACK_ALLOC(ucp, i); 789 ucp = STACK_MAX(arg1, i); 790 (void)copyout((void *)flags, arg1, i); 791 } 792 793 /* 794 * Move out the file name (also arg 0). 795 */ 796 i = strlen(path) + 1; 797 #ifdef DEBUG 798 printf("init: copying out path `%s' %d\n", path, i); 799 #else 800 if (boothowto & RB_ASKNAME || path != initpaths[0]) 801 printf("init: trying %s\n", path); 802 #endif 803 arg0 = STACK_ALLOC(ucp, i); 804 ucp = STACK_MAX(arg0, i); 805 (void)copyout(path, arg0, i); 806 807 /* 808 * Move out the arg pointers. 809 */ 810 ucp = (void *)STACK_ALIGN(ucp, ALIGNBYTES); 811 uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3); 812 SCARG(&args, path) = arg0; 813 SCARG(&args, argp) = uap; 814 SCARG(&args, envp) = NULL; 815 slash = strrchr(path, '/'); 816 if (slash) 817 (void)suword((void *)uap++, 818 (long)arg0 + (slash + 1 - path)); 819 else 820 (void)suword((void *)uap++, (long)arg0); 821 if (options != 0) 822 (void)suword((void *)uap++, (long)arg1); 823 (void)suword((void *)uap++, 0); /* terminator */ 824 825 /* 826 * Now try to exec the program. If can't for any reason 827 * other than it doesn't exist, complain. 828 */ 829 error = sys_execve(l, &args, retval); 830 if (error == 0 || error == EJUSTRETURN) { 831 KERNEL_UNLOCK_LAST(l); 832 return; 833 } 834 printf("exec %s: error %d\n", path, error); 835 } 836 printf("init: not found\n"); 837 panic("no init"); 838 } 839