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

Cache object: 250825ebd22c6c1186279ec32028aac7


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