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

Cache object: 589a2b136f32518006d8cffc5d357536


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