The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/init_main.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1995 Terrence R. Lambert
    3  * All rights reserved.
    4  *
    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  *
   41  *      @(#)init_main.c 8.9 (Berkeley) 1/21/94
   42  */
   43 
   44 #include <sys/cdefs.h>
   45 __FBSDID("$FreeBSD: releng/5.2/sys/kern/init_main.c 120659 2003-10-02 03:57:59Z rwatson $");
   46 
   47 #include "opt_init_path.h"
   48 #include "opt_mac.h"
   49 
   50 #include <sys/param.h>
   51 #include <sys/kernel.h>
   52 #include <sys/exec.h>
   53 #include <sys/file.h>
   54 #include <sys/filedesc.h>
   55 #include <sys/ktr.h>
   56 #include <sys/lock.h>
   57 #include <sys/mac.h>
   58 #include <sys/mount.h>
   59 #include <sys/mutex.h>
   60 #include <sys/syscallsubr.h>
   61 #include <sys/sysctl.h>
   62 #include <sys/proc.h>
   63 #include <sys/resourcevar.h>
   64 #include <sys/systm.h>
   65 #include <sys/signalvar.h>
   66 #include <sys/vnode.h>
   67 #include <sys/sysent.h>
   68 #include <sys/reboot.h>
   69 #include <sys/sched.h>
   70 #include <sys/sx.h>
   71 #include <sys/sysproto.h>
   72 #include <sys/vmmeter.h>
   73 #include <sys/unistd.h>
   74 #include <sys/malloc.h>
   75 #include <sys/conf.h>
   76 
   77 #include <machine/cpu.h>
   78 
   79 #include <vm/vm.h>
   80 #include <vm/vm_param.h>
   81 #include <vm/pmap.h>
   82 #include <vm/vm_map.h>
   83 #include <sys/user.h>
   84 #include <sys/copyright.h>
   85 
   86 void mi_startup(void);                          /* Should be elsewhere */
   87 
   88 /* Components of the first process -- never freed. */
   89 static struct session session0;
   90 static struct pgrp pgrp0;
   91 struct  proc proc0;
   92 struct  thread thread0;
   93 struct  kse kse0;
   94 struct  ksegrp ksegrp0;
   95 static struct filedesc0 filedesc0;
   96 static struct plimit limit0;
   97 struct  vmspace vmspace0;
   98 struct  proc *initproc;
   99 
  100 struct  vnode *rootvp;
  101 int     boothowto = 0;          /* initialized so that it can be patched */
  102 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
  103 int     bootverbose;
  104 SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
  105 
  106 /*
  107  * This ensures that there is at least one entry so that the sysinit_set
  108  * symbol is not undefined.  A sybsystem ID of SI_SUB_DUMMY is never
  109  * executed.
  110  */
  111 SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
  112 
  113 /*
  114  * The sysinit table itself.  Items are checked off as the are run.
  115  * If we want to register new sysinit types, add them to newsysinit.
  116  */
  117 SET_DECLARE(sysinit_set, struct sysinit);
  118 struct sysinit **sysinit, **sysinit_end;
  119 struct sysinit **newsysinit, **newsysinit_end;
  120 
  121 /*
  122  * Merge a new sysinit set into the current set, reallocating it if
  123  * necessary.  This can only be called after malloc is running.
  124  */
  125 void
  126 sysinit_add(struct sysinit **set, struct sysinit **set_end)
  127 {
  128         struct sysinit **newset;
  129         struct sysinit **sipp;
  130         struct sysinit **xipp;
  131         int count;
  132 
  133         count = set_end - set;
  134         if (newsysinit)
  135                 count += newsysinit_end - newsysinit;
  136         else
  137                 count += sysinit_end - sysinit;
  138         newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
  139         if (newset == NULL)
  140                 panic("cannot malloc for sysinit");
  141         xipp = newset;
  142         if (newsysinit)
  143                 for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
  144                         *xipp++ = *sipp;
  145         else
  146                 for (sipp = sysinit; sipp < sysinit_end; sipp++)
  147                         *xipp++ = *sipp;
  148         for (sipp = set; sipp < set_end; sipp++)
  149                 *xipp++ = *sipp;
  150         if (newsysinit)
  151                 free(newsysinit, M_TEMP);
  152         newsysinit = newset;
  153         newsysinit_end = newset + count;
  154 }
  155 
  156 /*
  157  * System startup; initialize the world, create process 0, mount root
  158  * filesystem, and fork to create init and pagedaemon.  Most of the
  159  * hard work is done in the lower-level initialization routines including
  160  * startup(), which does memory initialization and autoconfiguration.
  161  *
  162  * This allows simple addition of new kernel subsystems that require
  163  * boot time initialization.  It also allows substitution of subsystem
  164  * (for instance, a scheduler, kernel profiler, or VM system) by object
  165  * module.  Finally, it allows for optional "kernel threads".
  166  */
  167 void
  168 mi_startup(void)
  169 {
  170 
  171         register struct sysinit **sipp;         /* system initialization*/
  172         register struct sysinit **xipp;         /* interior loop of sort*/
  173         register struct sysinit *save;          /* bubble*/
  174 
  175         if (sysinit == NULL) {
  176                 sysinit = SET_BEGIN(sysinit_set);
  177                 sysinit_end = SET_LIMIT(sysinit_set);
  178         }
  179 
  180 restart:
  181         /*
  182          * Perform a bubble sort of the system initialization objects by
  183          * their subsystem (primary key) and order (secondary key).
  184          */
  185         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  186                 for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
  187                         if ((*sipp)->subsystem < (*xipp)->subsystem ||
  188                              ((*sipp)->subsystem == (*xipp)->subsystem &&
  189                               (*sipp)->order <= (*xipp)->order))
  190                                 continue;       /* skip*/
  191                         save = *sipp;
  192                         *sipp = *xipp;
  193                         *xipp = save;
  194                 }
  195         }
  196 
  197         /*
  198          * Traverse the (now) ordered list of system initialization tasks.
  199          * Perform each task, and continue on to the next task.
  200          *
  201          * The last item on the list is expected to be the scheduler,
  202          * which will not return.
  203          */
  204         for (sipp = sysinit; sipp < sysinit_end; sipp++) {
  205 
  206                 if ((*sipp)->subsystem == SI_SUB_DUMMY)
  207                         continue;       /* skip dummy task(s)*/
  208 
  209                 if ((*sipp)->subsystem == SI_SUB_DONE)
  210                         continue;
  211 
  212                 /* Call function */
  213                 (*((*sipp)->func))((*sipp)->udata);
  214 
  215                 /* Check off the one we're just done */
  216                 (*sipp)->subsystem = SI_SUB_DONE;
  217 
  218                 /* Check if we've installed more sysinit items via KLD */
  219                 if (newsysinit != NULL) {
  220                         if (sysinit != SET_BEGIN(sysinit_set))
  221                                 free(sysinit, M_TEMP);
  222                         sysinit = newsysinit;
  223                         sysinit_end = newsysinit_end;
  224                         newsysinit = NULL;
  225                         newsysinit_end = NULL;
  226                         goto restart;
  227                 }
  228         }
  229 
  230         panic("Shouldn't get here!");
  231         /* NOTREACHED*/
  232 }
  233 
  234 
  235 /*
  236  ***************************************************************************
  237  ****
  238  **** The following SYSINIT's belong elsewhere, but have not yet
  239  **** been moved.
  240  ****
  241  ***************************************************************************
  242  */
  243 static void
  244 print_caddr_t(void *data __unused)
  245 {
  246         printf("%s", (char *)data);
  247 }
  248 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
  249 SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, version)
  250 
  251 static void
  252 set_boot_verbose(void *data __unused)
  253 {
  254 
  255         if (boothowto & RB_VERBOSE)
  256                 bootverbose++;
  257 }
  258 SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
  259 
  260 struct sysentvec null_sysvec = {
  261         0,
  262         NULL,
  263         0,
  264         0,
  265         NULL,
  266         0,
  267         NULL,
  268         NULL,
  269         NULL,
  270         NULL,
  271         NULL,
  272         NULL,
  273         NULL,
  274         "null",
  275         NULL,
  276         NULL,
  277         0,
  278         PAGE_SIZE,
  279         VM_MIN_ADDRESS,
  280         VM_MAXUSER_ADDRESS,
  281         USRSTACK,
  282         PS_STRINGS,
  283         VM_PROT_ALL,
  284         NULL,
  285         NULL,
  286         NULL
  287 };
  288 
  289 /*
  290  ***************************************************************************
  291  ****
  292  **** The two following SYSINIT's are proc0 specific glue code.  I am not
  293  **** convinced that they can not be safely combined, but their order of
  294  **** operation has been maintained as the same as the original init_main.c
  295  **** for right now.
  296  ****
  297  **** These probably belong in init_proc.c or kern_proc.c, since they
  298  **** deal with proc0 (the fork template process).
  299  ****
  300  ***************************************************************************
  301  */
  302 /* ARGSUSED*/
  303 static void
  304 proc0_init(void *dummy __unused)
  305 {
  306         register struct proc            *p;
  307         register struct filedesc0       *fdp;
  308         register unsigned i;
  309         struct thread *td;
  310         struct ksegrp *kg;
  311         struct kse *ke;
  312 
  313         GIANT_REQUIRED;
  314         p = &proc0;
  315         td = &thread0;
  316         ke = &kse0;
  317         kg = &ksegrp0;
  318 
  319         ke->ke_sched = kse0_sched;
  320         kg->kg_sched = ksegrp0_sched;
  321         p->p_sched = proc0_sched;
  322         td->td_sched = thread0_sched;
  323 
  324         /*
  325          * Initialize magic number.
  326          */
  327         p->p_magic = P_MAGIC;
  328 
  329         /*
  330          * Initialize thread, process and pgrp structures.
  331          */
  332         procinit();
  333         threadinit();
  334 
  335         /*
  336          * Initialize sleep queue hash table
  337          */
  338         sleepinit();
  339 
  340         /*
  341          * additional VM structures
  342          */
  343         vm_init2();
  344 
  345         /*
  346          * Create process 0 (the swapper).
  347          */
  348         LIST_INSERT_HEAD(&allproc, p, p_list);
  349         LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
  350         mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
  351         p->p_pgrp = &pgrp0;
  352         LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
  353         LIST_INIT(&pgrp0.pg_members);
  354         LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
  355 
  356         pgrp0.pg_session = &session0;
  357         mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
  358         session0.s_count = 1;
  359         session0.s_leader = p;
  360 
  361         p->p_sysent = &null_sysvec;
  362 
  363         /*
  364          * proc_linkup was already done in init_i386() or alphainit() etc.
  365          * because the earlier code needed to follow td->td_proc. Otherwise
  366          * I would have done it here.. maybe this means this should be
  367          * done earlier too.
  368          */
  369         p->p_flag = P_SYSTEM;
  370         p->p_sflag = PS_INMEM;
  371         p->p_state = PRS_NORMAL;
  372         td->td_state = TDS_RUNNING;
  373         kg->kg_nice = NZERO;
  374         kg->kg_pri_class = PRI_TIMESHARE;
  375         kg->kg_user_pri = PUSER;
  376         td->td_priority = PVM;
  377         td->td_base_pri = PUSER;
  378         td->td_kse = ke; /* XXXKSE */
  379         td->td_oncpu = 0;
  380         ke->ke_state = KES_THREAD;
  381         ke->ke_thread = td;
  382         p->p_peers = 0;
  383         p->p_leader = p;
  384 
  385 
  386         bcopy("swapper", p->p_comm, sizeof ("swapper"));
  387 
  388         callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
  389         callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
  390 
  391         /* Create credentials. */
  392         p->p_ucred = crget();
  393         p->p_ucred->cr_ngroups = 1;     /* group 0 */
  394         p->p_ucred->cr_uidinfo = uifind(0);
  395         p->p_ucred->cr_ruidinfo = uifind(0);
  396         p->p_ucred->cr_prison = NULL;   /* Don't jail it. */
  397 #ifdef MAC
  398         mac_create_proc0(p->p_ucred);
  399 #endif
  400         td->td_ucred = crhold(p->p_ucred);
  401 
  402         /* Create sigacts. */
  403         p->p_sigacts = sigacts_alloc();
  404 
  405         /* Initialize signal state for process 0. */
  406         siginit(&proc0);
  407 
  408         /* Create the file descriptor table. */
  409         fdp = &filedesc0;
  410         p->p_fd = &fdp->fd_fd;
  411         p->p_fdtol = NULL;
  412         mtx_init(&fdp->fd_fd.fd_mtx, FILEDESC_LOCK_DESC, NULL, MTX_DEF);
  413         fdp->fd_fd.fd_refcnt = 1;
  414         fdp->fd_fd.fd_cmask = CMASK;
  415         fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
  416         fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
  417         fdp->fd_fd.fd_nfiles = NDFILE;
  418 
  419         /* Create the limits structures. */
  420         p->p_limit = &limit0;
  421         for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
  422                 limit0.pl_rlimit[i].rlim_cur =
  423                     limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
  424         limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
  425             limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
  426         limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
  427             limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  428         i = ptoa(cnt.v_free_count);
  429         limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
  430         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
  431         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
  432         limit0.p_refcnt = 1;
  433         p->p_cpulimit = RLIM_INFINITY;
  434 
  435         /* Allocate a prototype map so we have something to fork. */
  436         pmap_pinit0(vmspace_pmap(&vmspace0));
  437         p->p_vmspace = &vmspace0;
  438         vmspace0.vm_refcnt = 1;
  439         vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
  440             p->p_sysent->sv_maxuser);
  441         vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
  442 
  443         /*
  444          * We continue to place resource usage info
  445          * in the user struct so that it's pageable.
  446          */
  447         p->p_stats = &p->p_uarea->u_stats;
  448 
  449         /*
  450          * Charge root for one process.
  451          */
  452         (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
  453 }
  454 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
  455 
  456 /* ARGSUSED*/
  457 static void
  458 proc0_post(void *dummy __unused)
  459 {
  460         struct timespec ts;
  461         struct proc *p;
  462 
  463         /*
  464          * Now we can look at the time, having had a chance to verify the
  465          * time from the filesystem.  Pretend that proc0 started now.
  466          */
  467         sx_slock(&allproc_lock);
  468         LIST_FOREACH(p, &allproc, p_list) {
  469                 microuptime(&p->p_stats->p_start);
  470                 p->p_runtime.sec = 0;
  471                 p->p_runtime.frac = 0;
  472         }
  473         sx_sunlock(&allproc_lock);
  474         binuptime(PCPU_PTR(switchtime));
  475         PCPU_SET(switchticks, ticks);
  476 
  477         /*
  478          * Give the ``random'' number generator a thump.
  479          */
  480         nanotime(&ts);
  481         srandom(ts.tv_sec ^ ts.tv_nsec);
  482 }
  483 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
  484 
  485 /*
  486  ***************************************************************************
  487  ****
  488  **** The following SYSINIT's and glue code should be moved to the
  489  **** respective files on a per subsystem basis.
  490  ****
  491  ***************************************************************************
  492  */
  493 
  494 
  495 /*
  496  ***************************************************************************
  497  ****
  498  **** The following code probably belongs in another file, like
  499  **** kern/init_init.c.
  500  ****
  501  ***************************************************************************
  502  */
  503 
  504 /*
  505  * List of paths to try when searching for "init".
  506  */
  507 static char init_path[MAXPATHLEN] =
  508 #ifdef  INIT_PATH
  509     __XSTRING(INIT_PATH);
  510 #else
  511     "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall";
  512 #endif
  513 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
  514         "Path used to search the init process");
  515 
  516 /*
  517  * Start the initial user process; try exec'ing each pathname in init_path.
  518  * The program is invoked with one argument containing the boot flags.
  519  */
  520 static void
  521 start_init(void *dummy)
  522 {
  523         vm_offset_t addr;
  524         struct execve_args args;
  525         int options, error;
  526         char *var, *path, *next, *s;
  527         char *ucp, **uap, *arg0, *arg1;
  528         struct thread *td;
  529         struct proc *p;
  530         int init_does_devfs = 0;
  531 
  532         mtx_lock(&Giant);
  533 
  534         GIANT_REQUIRED;
  535 
  536         td = curthread;
  537         p = td->td_proc;
  538 
  539         vfs_mountroot();
  540 
  541         /* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
  542         if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode))
  543                 panic("cannot find root vnode");
  544         FILEDESC_LOCK(p->p_fd);
  545         p->p_fd->fd_cdir = rootvnode;
  546         VREF(p->p_fd->fd_cdir);
  547         p->p_fd->fd_rdir = rootvnode;
  548         VREF(p->p_fd->fd_rdir);
  549         FILEDESC_UNLOCK(p->p_fd);
  550         VOP_UNLOCK(rootvnode, 0, td);
  551 #ifdef MAC
  552         mac_create_root_mount(td->td_ucred, TAILQ_FIRST(&mountlist));
  553 #endif
  554 
  555         /*
  556          * For disk based systems, we probably cannot do this yet
  557          * since the fs will be read-only.  But a NFS root
  558          * might be ok.  It is worth a shot.
  559          */
  560         error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700);
  561         if (error == EEXIST)
  562                 error = 0;
  563         if (error == 0)
  564                 error = kernel_vmount(0, "fstype", "devfs",
  565                     "fspath", "/dev", NULL);
  566         if (error != 0)
  567                 init_does_devfs = 1;
  568 
  569         /*
  570          * Need just enough stack to hold the faked-up "execve()" arguments.
  571          */
  572         addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
  573         if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
  574                         FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
  575                 panic("init: couldn't allocate argument space");
  576         p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
  577         p->p_vmspace->vm_ssize = 1;
  578 
  579         if ((var = getenv("init_path")) != NULL) {
  580                 strlcpy(init_path, var, sizeof(init_path));
  581                 freeenv(var);
  582         }
  583         
  584         for (path = init_path; *path != '\0'; path = next) {
  585                 while (*path == ':')
  586                         path++;
  587                 if (*path == '\0')
  588                         break;
  589                 for (next = path; *next != '\0' && *next != ':'; next++)
  590                         /* nothing */ ;
  591                 if (bootverbose)
  592                         printf("start_init: trying %.*s\n", (int)(next - path),
  593                             path);
  594                         
  595                 /*
  596                  * Move out the boot flag argument.
  597                  */
  598                 options = 0;
  599                 ucp = (char *)p->p_sysent->sv_usrstack;
  600                 (void)subyte(--ucp, 0);         /* trailing zero */
  601                 if (boothowto & RB_SINGLE) {
  602                         (void)subyte(--ucp, 's');
  603                         options = 1;
  604                 }
  605 #ifdef notyet
  606                 if (boothowto & RB_FASTBOOT) {
  607                         (void)subyte(--ucp, 'f');
  608                         options = 1;
  609                 }
  610 #endif
  611 
  612 #ifdef BOOTCDROM
  613                 (void)subyte(--ucp, 'C');
  614                 options = 1;
  615 #endif
  616                 if (init_does_devfs) {
  617                         (void)subyte(--ucp, 'd');
  618                         options = 1;
  619                 }
  620 
  621                 if (options == 0)
  622                         (void)subyte(--ucp, '-');
  623                 (void)subyte(--ucp, '-');               /* leading hyphen */
  624                 arg1 = ucp;
  625 
  626                 /*
  627                  * Move out the file name (also arg 0).
  628                  */
  629                 (void)subyte(--ucp, 0);
  630                 for (s = next - 1; s >= path; s--)
  631                         (void)subyte(--ucp, *s);
  632                 arg0 = ucp;
  633 
  634                 /*
  635                  * Move out the arg pointers.
  636                  */
  637                 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
  638                 (void)suword((caddr_t)--uap, (long)0);  /* terminator */
  639                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
  640                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
  641 
  642                 /*
  643                  * Point at the arguments.
  644                  */
  645                 args.fname = arg0;
  646                 args.argv = uap;
  647                 args.envv = NULL;
  648 
  649                 /*
  650                  * Now try to exec the program.  If can't for any reason
  651                  * other than it doesn't exist, complain.
  652                  *
  653                  * Otherwise, return via fork_trampoline() all the way
  654                  * to user mode as init!
  655                  */
  656                 if ((error = execve(td, &args)) == 0) {
  657                         mtx_unlock(&Giant);
  658                         return;
  659                 }
  660                 if (error != ENOENT)
  661                         printf("exec %.*s: error %d\n", (int)(next - path), 
  662                             path, error);
  663         }
  664         printf("init: not found in path %s\n", init_path);
  665         panic("no init");
  666 }
  667 
  668 /*
  669  * Like kthread_create(), but runs in it's own address space.
  670  * We do this early to reserve pid 1.
  671  *
  672  * Note special case - do not make it runnable yet.  Other work
  673  * in progress will change this more.
  674  */
  675 static void
  676 create_init(const void *udata __unused)
  677 {
  678         struct ucred *newcred, *oldcred;
  679         int error;
  680 
  681         error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
  682         if (error)
  683                 panic("cannot fork init: %d\n", error);
  684         /* divorce init's credentials from the kernel's */
  685         newcred = crget();
  686         PROC_LOCK(initproc);
  687         initproc->p_flag |= P_SYSTEM;
  688         oldcred = initproc->p_ucred;
  689         crcopy(newcred, oldcred);
  690 #ifdef MAC
  691         mac_create_proc1(newcred);
  692 #endif
  693         initproc->p_ucred = newcred;
  694         PROC_UNLOCK(initproc);
  695         crfree(oldcred);
  696         cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
  697         mtx_lock_spin(&sched_lock);
  698         initproc->p_sflag |= PS_INMEM;
  699         mtx_unlock_spin(&sched_lock);
  700         cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
  701 }
  702 SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
  703 
  704 /*
  705  * Make it runnable now.
  706  */
  707 static void
  708 kick_init(const void *udata __unused)
  709 {
  710         struct thread *td;
  711 
  712         td = FIRST_THREAD_IN_PROC(initproc);
  713         mtx_lock_spin(&sched_lock);
  714         TD_SET_CAN_RUN(td);
  715         setrunqueue(td);        /* XXXKSE */
  716         mtx_unlock_spin(&sched_lock);
  717 }
  718 SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)

Cache object: eefd88f96aeb0f9bb868d615a6bbea73


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.