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

Cache object: 29a9c517e20324f8f06fcd57c769271a


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