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  * $FreeBSD: releng/5.1/sys/kern/init_main.c 114983 2003-05-13 20:36:02Z jhb $
   43  */
   44 
   45 #include "opt_init_path.h"
   46 #include "opt_mac.h"
   47 
   48 #include <sys/param.h>
   49 #include <sys/kernel.h>
   50 #include <sys/exec.h>
   51 #include <sys/file.h>
   52 #include <sys/filedesc.h>
   53 #include <sys/ktr.h>
   54 #include <sys/lock.h>
   55 #include <sys/mac.h>
   56 #include <sys/mount.h>
   57 #include <sys/mutex.h>
   58 #include <sys/syscallsubr.h>
   59 #include <sys/sysctl.h>
   60 #include <sys/proc.h>
   61 #include <sys/resourcevar.h>
   62 #include <sys/systm.h>
   63 #include <sys/signalvar.h>
   64 #include <sys/vnode.h>
   65 #include <sys/sysent.h>
   66 #include <sys/reboot.h>
   67 #include <sys/sched.h>
   68 #include <sys/sx.h>
   69 #include <sys/sysproto.h>
   70 #include <sys/vmmeter.h>
   71 #include <sys/unistd.h>
   72 #include <sys/malloc.h>
   73 #include <sys/conf.h>
   74 
   75 #include <machine/cpu.h>
   76 
   77 #include <vm/vm.h>
   78 #include <vm/vm_param.h>
   79 #include <vm/pmap.h>
   80 #include <vm/vm_map.h>
   81 #include <sys/user.h>
   82 #include <sys/copyright.h>
   83 
   84 void mi_startup(void);                          /* Should be elsewhere */
   85 
   86 /* Components of the first process -- never freed. */
   87 static struct session session0;
   88 static struct pgrp pgrp0;
   89 struct  proc proc0;
   90 struct  thread thread0;
   91 struct  kse kse0;
   92 struct  ksegrp ksegrp0;
   93 static struct filedesc0 filedesc0;
   94 static struct plimit limit0;
   95 struct  vmspace vmspace0;
   96 struct  proc *initproc;
   97 
   98 int cmask = CMASK;
   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 };
  287 
  288 /*
  289  ***************************************************************************
  290  ****
  291  **** The two following SYSINIT's are proc0 specific glue code.  I am not
  292  **** convinced that they can not be safely combined, but their order of
  293  **** operation has been maintained as the same as the original init_main.c
  294  **** for right now.
  295  ****
  296  **** These probably belong in init_proc.c or kern_proc.c, since they
  297  **** deal with proc0 (the fork template process).
  298  ****
  299  ***************************************************************************
  300  */
  301 /* ARGSUSED*/
  302 static void
  303 proc0_init(void *dummy __unused)
  304 {
  305         register struct proc            *p;
  306         register struct filedesc0       *fdp;
  307         register unsigned i;
  308         struct thread *td;
  309         struct ksegrp *kg;
  310         struct kse *ke;
  311 
  312         GIANT_REQUIRED;
  313         p = &proc0;
  314         td = &thread0;
  315         ke = &kse0;
  316         kg = &ksegrp0;
  317 
  318         ke->ke_sched = kse0_sched;
  319         kg->kg_sched = ksegrp0_sched;
  320         p->p_sched = proc0_sched;
  321         td->td_sched = thread0_sched;
  322 
  323         /*
  324          * Initialize magic number.
  325          */
  326         p->p_magic = P_MAGIC;
  327 
  328         /*
  329          * Initialize thread, process and pgrp structures.
  330          */
  331         procinit();
  332         threadinit();
  333 
  334         /*
  335          * Initialize sleep queue hash table
  336          */
  337         sleepinit();
  338 
  339         /*
  340          * additional VM structures
  341          */
  342         vm_init2();
  343 
  344         /*
  345          * Create process 0 (the swapper).
  346          */
  347         LIST_INSERT_HEAD(&allproc, p, p_list);
  348         LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
  349         mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
  350         p->p_pgrp = &pgrp0;
  351         LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
  352         LIST_INIT(&pgrp0.pg_members);
  353         LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
  354 
  355         pgrp0.pg_session = &session0;
  356         mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
  357         session0.s_count = 1;
  358         session0.s_leader = p;
  359 
  360         p->p_sysent = &null_sysvec;
  361 
  362         /*
  363          * proc_linkup was already done in init_i386() or alphainit() etc.
  364          * because the earlier code needed to follow td->td_proc. Otherwise
  365          * I would have done it here.. maybe this means this should be
  366          * done earlier too.
  367          */
  368         p->p_flag = P_SYSTEM;
  369         p->p_sflag = PS_INMEM;
  370         p->p_state = PRS_NORMAL;
  371         td->td_state = TDS_RUNNING;
  372         kg->kg_nice = NZERO;
  373         kg->kg_pri_class = PRI_TIMESHARE;
  374         kg->kg_user_pri = PUSER;
  375         td->td_priority = PVM;
  376         td->td_base_pri = PUSER;
  377         td->td_kse = ke; /* XXXKSE */
  378         td->td_oncpu = 0;
  379         ke->ke_state = KES_THREAD;
  380         ke->ke_thread = td;
  381         p->p_peers = 0;
  382         p->p_leader = p;
  383 
  384 
  385         bcopy("swapper", p->p_comm, sizeof ("swapper"));
  386 
  387         callout_init(&p->p_itcallout, 1);
  388         callout_init(&td->td_slpcallout, 1);
  389 
  390         /* Create credentials. */
  391         p->p_ucred = crget();
  392         p->p_ucred->cr_ngroups = 1;     /* group 0 */
  393         p->p_ucred->cr_uidinfo = uifind(0);
  394         p->p_ucred->cr_ruidinfo = uifind(0);
  395         p->p_ucred->cr_prison = NULL;   /* Don't jail it. */
  396 #ifdef MAC
  397         mac_create_proc0(p->p_ucred);
  398 #endif
  399         td->td_ucred = crhold(p->p_ucred);
  400 
  401         /* Create sigacts. */
  402         p->p_sigacts = sigacts_alloc();
  403 
  404         /* Initialize signal state for process 0. */
  405         siginit(&proc0);
  406 
  407         /* Create the file descriptor table. */
  408         fdp = &filedesc0;
  409         p->p_fd = &fdp->fd_fd;
  410         mtx_init(&fdp->fd_fd.fd_mtx, FILEDESC_LOCK_DESC, NULL, MTX_DEF);
  411         fdp->fd_fd.fd_refcnt = 1;
  412         fdp->fd_fd.fd_cmask = cmask;
  413         fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
  414         fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
  415         fdp->fd_fd.fd_nfiles = NDFILE;
  416 
  417         /* Create the limits structures. */
  418         p->p_limit = &limit0;
  419         for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
  420                 limit0.pl_rlimit[i].rlim_cur =
  421                     limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
  422         limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
  423             limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
  424         limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
  425             limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  426         i = ptoa(cnt.v_free_count);
  427         limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
  428         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
  429         limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
  430         limit0.p_refcnt = 1;
  431         p->p_cpulimit = RLIM_INFINITY;
  432 
  433         /* Allocate a prototype map so we have something to fork. */
  434         pmap_pinit0(vmspace_pmap(&vmspace0));
  435         p->p_vmspace = &vmspace0;
  436         vmspace0.vm_refcnt = 1;
  437         vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
  438             p->p_sysent->sv_maxuser);
  439         vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
  440 
  441         /*
  442          * We continue to place resource usage info
  443          * in the user struct so that it's pageable.
  444          */
  445         p->p_stats = &p->p_uarea->u_stats;
  446 
  447         /*
  448          * Charge root for one process.
  449          */
  450         (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
  451 }
  452 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
  453 
  454 /* ARGSUSED*/
  455 static void
  456 proc0_post(void *dummy __unused)
  457 {
  458         struct timespec ts;
  459         struct proc *p;
  460 
  461         /*
  462          * Now we can look at the time, having had a chance to verify the
  463          * time from the filesystem.  Pretend that proc0 started now.
  464          */
  465         sx_slock(&allproc_lock);
  466         LIST_FOREACH(p, &allproc, p_list) {
  467                 microuptime(&p->p_stats->p_start);
  468                 p->p_runtime.sec = 0;
  469                 p->p_runtime.frac = 0;
  470         }
  471         sx_sunlock(&allproc_lock);
  472         binuptime(PCPU_PTR(switchtime));
  473         PCPU_SET(switchticks, ticks);
  474 
  475         /*
  476          * Give the ``random'' number generator a thump.
  477          */
  478         nanotime(&ts);
  479         srandom(ts.tv_sec ^ ts.tv_nsec);
  480 }
  481 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
  482 
  483 /*
  484  ***************************************************************************
  485  ****
  486  **** The following SYSINIT's and glue code should be moved to the
  487  **** respective files on a per subsystem basis.
  488  ****
  489  ***************************************************************************
  490  */
  491 
  492 
  493 /*
  494  ***************************************************************************
  495  ****
  496  **** The following code probably belongs in another file, like
  497  **** kern/init_init.c.
  498  ****
  499  ***************************************************************************
  500  */
  501 
  502 /*
  503  * List of paths to try when searching for "init".
  504  */
  505 static char init_path[MAXPATHLEN] =
  506 #ifdef  INIT_PATH
  507     __XSTRING(INIT_PATH);
  508 #else
  509     "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall";
  510 #endif
  511 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
  512         "Path used to search the init process");
  513 
  514 /*
  515  * Start the initial user process; try exec'ing each pathname in init_path.
  516  * The program is invoked with one argument containing the boot flags.
  517  */
  518 static void
  519 start_init(void *dummy)
  520 {
  521         vm_offset_t addr;
  522         struct execve_args args;
  523         int options, error;
  524         char *var, *path, *next, *s;
  525         char *ucp, **uap, *arg0, *arg1;
  526         struct thread *td;
  527         struct proc *p;
  528         int init_does_devfs = 0;
  529 
  530         mtx_lock(&Giant);
  531 
  532         GIANT_REQUIRED;
  533 
  534         td = curthread;
  535         p = td->td_proc;
  536 
  537         vfs_mountroot();
  538 
  539         /* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
  540         if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode))
  541                 panic("cannot find root vnode");
  542         FILEDESC_LOCK(p->p_fd);
  543         p->p_fd->fd_cdir = rootvnode;
  544         VREF(p->p_fd->fd_cdir);
  545         p->p_fd->fd_rdir = rootvnode;
  546         VREF(p->p_fd->fd_rdir);
  547         FILEDESC_UNLOCK(p->p_fd);
  548         VOP_UNLOCK(rootvnode, 0, td);
  549 #ifdef MAC
  550         mac_create_root_mount(td->td_ucred, TAILQ_FIRST(&mountlist));
  551 #endif
  552 
  553         /*
  554          * For disk based systems, we probably cannot do this yet
  555          * since the fs will be read-only.  But a NFS root
  556          * might be ok.  It is worth a shot.
  557          */
  558         error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700);
  559         if (error == EEXIST)
  560                 error = 0;
  561         if (error == 0)
  562                 error = kernel_vmount(0, "fstype", "devfs",
  563                     "fspath", "/dev", NULL);
  564         if (error != 0)
  565                 init_does_devfs = 1;
  566 
  567         /*
  568          * Need just enough stack to hold the faked-up "execve()" arguments.
  569          */
  570         addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
  571         if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
  572                         FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
  573                 panic("init: couldn't allocate argument space");
  574         p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
  575         p->p_vmspace->vm_ssize = 1;
  576 
  577         if ((var = getenv("init_path")) != NULL) {
  578                 strlcpy(init_path, var, sizeof(init_path));
  579                 freeenv(var);
  580         }
  581         
  582         for (path = init_path; *path != '\0'; path = next) {
  583                 while (*path == ':')
  584                         path++;
  585                 if (*path == '\0')
  586                         break;
  587                 for (next = path; *next != '\0' && *next != ':'; next++)
  588                         /* nothing */ ;
  589                 if (bootverbose)
  590                         printf("start_init: trying %.*s\n", (int)(next - path),
  591                             path);
  592                         
  593                 /*
  594                  * Move out the boot flag argument.
  595                  */
  596                 options = 0;
  597                 ucp = (char *)p->p_sysent->sv_usrstack;
  598                 (void)subyte(--ucp, 0);         /* trailing zero */
  599                 if (boothowto & RB_SINGLE) {
  600                         (void)subyte(--ucp, 's');
  601                         options = 1;
  602                 }
  603 #ifdef notyet
  604                 if (boothowto & RB_FASTBOOT) {
  605                         (void)subyte(--ucp, 'f');
  606                         options = 1;
  607                 }
  608 #endif
  609 
  610 #ifdef BOOTCDROM
  611                 (void)subyte(--ucp, 'C');
  612                 options = 1;
  613 #endif
  614                 if (init_does_devfs) {
  615                         (void)subyte(--ucp, 'd');
  616                         options = 1;
  617                 }
  618 
  619                 if (options == 0)
  620                         (void)subyte(--ucp, '-');
  621                 (void)subyte(--ucp, '-');               /* leading hyphen */
  622                 arg1 = ucp;
  623 
  624                 /*
  625                  * Move out the file name (also arg 0).
  626                  */
  627                 (void)subyte(--ucp, 0);
  628                 for (s = next - 1; s >= path; s--)
  629                         (void)subyte(--ucp, *s);
  630                 arg0 = ucp;
  631 
  632                 /*
  633                  * Move out the arg pointers.
  634                  */
  635                 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
  636                 (void)suword((caddr_t)--uap, (long)0);  /* terminator */
  637                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
  638                 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
  639 
  640                 /*
  641                  * Point at the arguments.
  642                  */
  643                 args.fname = arg0;
  644                 args.argv = uap;
  645                 args.envv = NULL;
  646 
  647                 /*
  648                  * Now try to exec the program.  If can't for any reason
  649                  * other than it doesn't exist, complain.
  650                  *
  651                  * Otherwise, return via fork_trampoline() all the way
  652                  * to user mode as init!
  653                  */
  654                 if ((error = execve(td, &args)) == 0) {
  655                         mtx_unlock(&Giant);
  656                         return;
  657                 }
  658                 if (error != ENOENT)
  659                         printf("exec %.*s: error %d\n", (int)(next - path), 
  660                             path, error);
  661         }
  662         printf("init: not found in path %s\n", init_path);
  663         panic("no init");
  664 }
  665 
  666 /*
  667  * Like kthread_create(), but runs in it's own address space.
  668  * We do this early to reserve pid 1.
  669  *
  670  * Note special case - do not make it runnable yet.  Other work
  671  * in progress will change this more.
  672  */
  673 static void
  674 create_init(const void *udata __unused)
  675 {
  676         struct ucred *newcred, *oldcred;
  677         int error;
  678 
  679         error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
  680         if (error)
  681                 panic("cannot fork init: %d\n", error);
  682         /* divorce init's credentials from the kernel's */
  683         newcred = crget();
  684         PROC_LOCK(initproc);
  685         initproc->p_flag |= P_SYSTEM;
  686         oldcred = initproc->p_ucred;
  687         crcopy(newcred, oldcred);
  688 #ifdef MAC
  689         mac_create_proc1(newcred);
  690 #endif
  691         initproc->p_ucred = newcred;
  692         PROC_UNLOCK(initproc);
  693         crfree(oldcred);
  694         cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
  695         mtx_lock_spin(&sched_lock);
  696         initproc->p_sflag |= PS_INMEM;
  697         mtx_unlock_spin(&sched_lock);
  698         cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
  699 }
  700 SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
  701 
  702 /*
  703  * Make it runnable now.
  704  */
  705 static void
  706 kick_init(const void *udata __unused)
  707 {
  708         struct thread *td;
  709 
  710         td = FIRST_THREAD_IN_PROC(initproc);
  711         mtx_lock_spin(&sched_lock);
  712         TD_SET_CAN_RUN(td);
  713         setrunqueue(td);        /* XXXKSE */
  714         mtx_unlock_spin(&sched_lock);
  715 }
  716 SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)

Cache object: a736e26d80f376d5aa65e50f73c67549


[ 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.