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/bsd/kern/bsd_init.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) 2000-2007 Apple Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 /*
   29  * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
   30  *      The Regents of the University of California.  All rights reserved.
   31  * (c) UNIX System Laboratories, Inc.
   32  * All or some portions of this file are derived from material licensed
   33  * to the University of California by American Telephone and Telegraph
   34  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   35  * the permission of UNIX System Laboratories, Inc.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. All advertising materials mentioning features or use of this software
   46  *    must display the following acknowledgement:
   47  *      This product includes software developed by the University of
   48  *      California, Berkeley and its contributors.
   49  * 4. Neither the name of the University nor the names of its contributors
   50  *    may be used to endorse or promote products derived from this software
   51  *    without specific prior written permission.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   63  * SUCH DAMAGE.
   64  *
   65  *      @(#)init_main.c 8.16 (Berkeley) 5/14/95
   66  */
   67 
   68 /* 
   69  *
   70  * Mach Operating System
   71  * Copyright (c) 1987 Carnegie-Mellon University
   72  * All rights reserved.  The CMU software License Agreement specifies
   73  * the terms and conditions for use and redistribution.
   74  */
   75 /*
   76  * NOTICE: This file was modified by McAfee Research in 2004 to introduce
   77  * support for mandatory and extensible security protections.  This notice
   78  * is included in support of clause 2.2 (b) of the Apple Public License,
   79  * Version 2.0.
   80  */
   81 
   82 #include <sys/param.h>
   83 #include <sys/filedesc.h>
   84 #include <sys/kernel.h>
   85 #include <sys/mount_internal.h>
   86 #include <sys/proc_internal.h>
   87 #include <sys/kauth.h>
   88 #include <sys/systm.h>
   89 #include <sys/vnode_internal.h>
   90 #include <sys/conf.h>
   91 #include <sys/buf_internal.h>
   92 #include <sys/clist.h>
   93 #include <sys/user.h>
   94 #include <sys/time.h>
   95 #include <sys/systm.h>
   96 #include <sys/mman.h>
   97 
   98 #include <bsm/audit_kernel.h>
   99 
  100 #include <sys/malloc.h>
  101 #include <sys/dkstat.h>
  102 #include <sys/codesign.h>
  103 
  104 #include <kern/startup.h>
  105 #include <kern/thread.h>
  106 #include <kern/task.h>
  107 #include <kern/ast.h>
  108 
  109 #include <mach/vm_param.h>
  110 
  111 #include <vm/vm_map.h>
  112 #include <vm/vm_kern.h>
  113 
  114 #include <sys/ux_exception.h>   /* for ux_exception_port */
  115 
  116 #include <sys/reboot.h>
  117 #include <mach/exception_types.h>
  118 #include <dev/busvar.h>                 /* for pseudo_inits */
  119 #include <sys/kdebug.h>
  120 
  121 #include <mach/mach_types.h>
  122 #include <mach/vm_prot.h>
  123 #include <mach/semaphore.h>
  124 #include <mach/sync_policy.h>
  125 #include <kern/clock.h>
  126 #include <mach/kern_return.h>
  127 #include <mach/thread_act.h>            /* for thread_resume() */
  128 #include <mach/task.h>                  /* for task_set_exception_ports() */
  129 #include <sys/ux_exception.h>           /* for ux_handler() */
  130 #include <sys/ubc_internal.h>           /* for ubc_init() */
  131 #include <sys/mcache.h>                 /* for mcache_init() */
  132 #include <sys/mbuf.h>                   /* for mbinit() */
  133 #include <sys/event.h>                  /* for knote_init() */
  134 #include <sys/aio_kern.h>               /* for aio_init() */
  135 #include <sys/semaphore.h>              /* for psem_cache_init() */
  136 #include <net/dlil.h>                   /* for dlil_init() */
  137 #include <net/kpi_protocol.h>           /* for proto_kpi_init() */
  138 #include <sys/pipe.h>                   /* for pipeinit() */
  139 #include <sys/socketvar.h>              /* for socketinit() */
  140 #include <sys/protosw.h>                /* for domaininit() */
  141 #include <kern/sched_prim.h>            /* for thread_wakeup() */
  142 #include <net/if_ether.h>               /* for ether_family_init() */
  143 #include <vm/vm_protos.h>               /* for vnode_pager_bootstrap() */
  144 #include <miscfs/devfs/devfsdefs.h>     /* for devfs_kernel_mount() */
  145 #include <mach/host_priv.h>             /* for host_set_exception_ports() */
  146 #include <kern/host.h>                  /* for host_priv_self() */
  147 #include <vm/vm_kern.h>                 /* for kmem_suballoc() */
  148 #include <sys/semaphore.h>              /* for psem_lock_init() */
  149 #include <sys/msgbuf.h>                 /* for log_setsize() */
  150 
  151 #include <net/init.h>
  152 
  153 #if CONFIG_MACF
  154 #include <security/mac_framework.h>
  155 #include <security/mac_internal.h>      /* mac_init_bsd() */
  156 #include <security/mac_mach_internal.h> /* mac_update_task_label() */
  157 #endif
  158 
  159 #include <machine/exec.h>
  160 
  161 #if CONFIG_IMAGEBOOT
  162 #include <sys/imageboot.h>
  163 #endif
  164 
  165 #include <pexpert/pexpert.h>
  166 
  167 void * get_user_regs(thread_t);         /* XXX kludge for <machine/thread.h> */
  168 void IOKitInitializeTime(void);         /* XXX */
  169 void loopattach(void);                  /* XXX */
  170 
  171 char    copyright[] =
  172 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\t"
  173 "The Regents of the University of California. "
  174 "All rights reserved.\n\n";
  175 
  176 /* Components of the first process -- never freed. */
  177 struct  proc proc0;
  178 struct  session session0;
  179 struct  pgrp pgrp0;
  180 struct  filedesc filedesc0;
  181 struct  plimit limit0;
  182 struct  pstats pstats0;
  183 struct  sigacts sigacts0;
  184 proc_t kernproc;
  185 proc_t initproc;
  186 
  187 long tk_cancc;
  188 long tk_nin;
  189 long tk_nout;
  190 long tk_rawcc;
  191 
  192 int lock_trace = 0;
  193 /* Global variables to make pstat happy. We do swapping differently */
  194 int nswdev, nswap;
  195 int nswapmap;
  196 void *swapmap;
  197 struct swdevt swdevt[1];
  198 
  199 dev_t   rootdev;                /* device of the root */
  200 dev_t   dumpdev;                /* device to take dumps on */
  201 long    dumplo;                 /* offset into dumpdev */
  202 long    hostid;
  203 char    hostname[MAXHOSTNAMELEN];
  204 int             hostnamelen;
  205 char    domainname[MAXDOMNAMELEN];
  206 int             domainnamelen;
  207 #if __i386__
  208 struct exec_archhandler exec_archhandler_ppc = {
  209         .path = "/usr/libexec/oah/translate",
  210 };
  211 #else /* __i386__ */
  212 struct exec_archhandler exec_archhandler_ppc;
  213 #endif /* __i386__ */
  214 
  215 char rootdevice[16];    /* hfs device names have at least 9 chars */
  216 
  217 #if  KMEMSTATS
  218 struct  kmemstats kmemstats[M_LAST];
  219 #endif
  220 
  221 int     lbolt;                          /* awoken once a second */
  222 struct  vnode *rootvp;
  223 int boothowto = RB_DEBUG;
  224 
  225 void lightning_bolt(void *);
  226 extern kern_return_t IOFindBSDRoot(char *, dev_t *, u_int32_t *);
  227 extern void IOSecureBSDRoot(const char * rootName);
  228 extern kern_return_t IOKitBSDInit(void );
  229 extern void kminit(void);
  230 extern void klogwakeup(void);
  231 extern void file_lock_init(void);
  232 extern void kmeminit(void);
  233 extern void bsd_bufferinit(void);
  234 
  235 extern int srv;
  236 extern int ncl;
  237 
  238 #define BSD_SIMUL_EXECS       33 /* 32 , allow for rounding */
  239 #define BSD_PAGABLE_MAP_SIZE    (BSD_SIMUL_EXECS * (NCARGS + PAGE_SIZE))
  240 vm_map_t        bsd_pageable_map;
  241 vm_map_t        mb_map;
  242 semaphore_t execve_semaphore;
  243 
  244 int     cmask = CMASK;
  245 extern int customnbuf;
  246 
  247 void bsd_init(void) __attribute__((section("__TEXT, initcode")));
  248 __private_extern__ void ubc_init(void )  __attribute__((section("__TEXT, initcode")));
  249 void vfsinit(void) __attribute__((section("__TEXT, initcode")));
  250 kern_return_t bsd_autoconf(void) __attribute__((section("__TEXT, initcode")));
  251 void bsd_utaskbootstrap(void) __attribute__((section("__TEXT, initcode")));
  252 
  253 static void parse_bsd_args(void);
  254 extern task_t bsd_init_task;
  255 extern char    init_task_failure_data[];
  256 extern void time_zone_slock_init(void);
  257 static void process_name(const char *, proc_t);
  258 
  259 static void setconf(void);
  260 
  261 funnel_t *kernel_flock;
  262 
  263 #if SYSV_SHM
  264 extern void sysv_shm_lock_init(void);
  265 #endif
  266 #if SYSV_SEM
  267 extern void sysv_sem_lock_init(void);
  268 #endif
  269 #if SYSV_MSG
  270 extern void sysv_msg_lock_init(void);
  271 #endif
  272 extern void pthread_init(void);
  273 
  274 /* kmem access not enabled by default; can be changed with boot-args */
  275 int setup_kmem = 0;
  276 
  277 /* size of kernel trace buffer, disabled by default */
  278 unsigned int new_nkdbufs = 0;
  279 
  280 /* mach leak logging */
  281 int log_leaks = 0;
  282 int turn_on_log_leaks = 0;
  283 
  284 extern void stackshot_lock_init(void);
  285 
  286 /*
  287  * Initialization code.
  288  * Called from cold start routine as
  289  * soon as a stack and segmentation
  290  * have been established.
  291  * Functions:
  292  *      turn on clock
  293  *      hand craft 0th process
  294  *      call all initialization routines
  295  *  hand craft 1st user process
  296  */
  297 
  298 /*
  299  *      Sets the name for the given task.
  300  */
  301 static void
  302 process_name(const char *s, proc_t p)
  303 {
  304         size_t length = strlen(s);
  305 
  306         bcopy(s, p->p_comm,
  307                 length >= sizeof(p->p_comm) ? sizeof(p->p_comm) :
  308                         length + 1);
  309 }
  310 
  311 /* To allow these values to be patched, they're globals here */
  312 #include <machine/vmparam.h>
  313 struct rlimit vm_initial_limit_stack = { DFLSSIZ, MAXSSIZ - PAGE_SIZE };
  314 struct rlimit vm_initial_limit_data = { DFLDSIZ, MAXDSIZ };
  315 struct rlimit vm_initial_limit_core = { DFLCSIZ, MAXCSIZ };
  316 
  317 extern thread_t cloneproc(proc_t, int);
  318 extern int      (*mountroot)(void);
  319 extern int      netboot_mountroot(void);        /* netboot.c */
  320 extern int      netboot_setup(void);
  321 
  322 lck_grp_t * proc_lck_grp;
  323 lck_grp_attr_t * proc_lck_grp_attr;
  324 lck_attr_t * proc_lck_attr;
  325 lck_mtx_t * proc_list_mlock;
  326 lck_mtx_t * proc_klist_mlock;
  327 
  328 /* hook called after root is mounted XXX temporary hack */
  329 void (*mountroot_post_hook)(void);
  330 
  331 /*
  332  * This function is called very early on in the Mach startup, from the
  333  * function start_kernel_threads() in osfmk/kern/startup.c.  It's called
  334  * in the context of the current (startup) task using a call to the
  335  * function kernel_thread_create() to jump into start_kernel_threads().
  336  * Internally, kernel_thread_create() calls thread_create_internal(),
  337  * which calls uthread_alloc().  The function of uthread_alloc() is
  338  * normally to allocate a uthread structure, and fill out the uu_sigmask,
  339  * uu_context fields.  It skips filling these out in the case of the "task"
  340  * being "kernel_task", because the order of operation is inverted.  To
  341  * account for that, we need to manually fill in at least the contents
  342  * of the uu_context.vc_ucred field so that the uthread structure can be
  343  * used like any other.
  344  */
  345 void
  346 bsd_init(void)
  347 {
  348         proc_t p;
  349         struct uthread *ut;
  350         unsigned int i;
  351 #if __i386__
  352         int error;
  353 #endif  
  354         struct vfs_context context;
  355         kern_return_t   ret;
  356         struct ucred temp_cred;
  357 
  358 #define bsd_init_kprintf(x...) /* kprintf("bsd_init: " x) */
  359 
  360         kernel_flock = funnel_alloc(KERNEL_FUNNEL);
  361         if (kernel_flock == (funnel_t *)0 ) {
  362                 panic("bsd_init: Failed to allocate kernel funnel");
  363         }
  364         
  365         printf(copyright);
  366         
  367         bsd_init_kprintf("calling kmeminit\n");
  368         kmeminit();
  369         
  370         bsd_init_kprintf("calling parse_bsd_args\n");
  371         parse_bsd_args();
  372 
  373         /* Initialize kauth subsystem before instancing the first credential */
  374         bsd_init_kprintf("calling kauth_init\n");
  375         kauth_init();
  376 
  377         /* Initialize process and pgrp structures. */
  378         bsd_init_kprintf("calling procinit\n");
  379         procinit();
  380 
  381         kernproc = &proc0;
  382 
  383         p = kernproc;
  384 
  385         /* kernel_task->proc = kernproc; */
  386         set_bsdtask_info(kernel_task,(void *)p);
  387         p->p_pid = 0;
  388         p->p_ppid = 0;
  389 
  390         /* give kernproc a name */
  391         bsd_init_kprintf("calling process_name\n");
  392         process_name("kernel_task", p);
  393 
  394         /* allocate proc lock group attribute and group */
  395         bsd_init_kprintf("calling lck_grp_attr_alloc_init\n");
  396         proc_lck_grp_attr= lck_grp_attr_alloc_init();
  397         
  398         proc_lck_grp = lck_grp_alloc_init("proc",  proc_lck_grp_attr);
  399 
  400         /* Allocate proc lock attribute */
  401         proc_lck_attr = lck_attr_alloc_init();
  402 #if 0
  403 #if __PROC_INTERNAL_DEBUG
  404         lck_attr_setdebug(proc_lck_attr);
  405 #endif
  406 #endif
  407 
  408         proc_list_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr);
  409         proc_klist_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr);
  410         lck_mtx_init(&p->p_mlock, proc_lck_grp, proc_lck_attr);
  411         lck_mtx_init(&p->p_fdmlock, proc_lck_grp, proc_lck_attr);
  412         lck_spin_init(&p->p_slock, proc_lck_grp, proc_lck_attr);
  413 
  414         if (current_task() != kernel_task)
  415                 printf("bsd_init: We have a problem, "
  416                                 "current task is not kernel task\n");
  417         
  418         bsd_init_kprintf("calling get_bsdthread_info\n");
  419         ut = (uthread_t)get_bsdthread_info(current_thread());
  420 
  421 #if CONFIG_MACF
  422         /*
  423          * Initialize the MAC Framework
  424          */
  425         mac_policy_initbsd();
  426         p->p_mac_enforce = 0;
  427 #endif /* MAC */
  428 
  429         /*
  430          * Create process 0.
  431          */
  432         proc_list_lock();
  433         LIST_INSERT_HEAD(&allproc, p, p_list);
  434         p->p_pgrp = &pgrp0;
  435         LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
  436         LIST_INIT(&pgrp0.pg_members);
  437         lck_mtx_init(&pgrp0.pg_mlock, proc_lck_grp, proc_lck_attr);
  438         /* There is no other bsd thread this point and is safe without pgrp lock */
  439         LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
  440         p->p_listflag |= P_LIST_INPGRP;
  441         p->p_pgrpid = 0;
  442 
  443         pgrp0.pg_session = &session0;
  444         pgrp0.pg_membercnt = 1;
  445 
  446         session0.s_count = 1;
  447         session0.s_leader = p;
  448         session0.s_listflags = 0;
  449         lck_mtx_init(&session0.s_mlock, proc_lck_grp, proc_lck_attr);
  450         LIST_INSERT_HEAD(SESSHASH(0), &session0, s_hash);
  451         proc_list_unlock();
  452 
  453 #if CONFIG_LCTX
  454         p->p_lctx = NULL;
  455 #endif
  456 
  457         p->task = kernel_task;
  458         
  459         p->p_stat = SRUN;
  460         p->p_flag = P_SYSTEM;
  461         p->p_nice = NZERO;
  462         p->p_pptr = p;
  463 
  464         TAILQ_INIT(&p->p_uthlist);
  465         TAILQ_INSERT_TAIL(&p->p_uthlist, ut, uu_list);
  466         
  467         p->sigwait = FALSE;
  468         p->sigwait_thread = THREAD_NULL;
  469         p->exit_thread = THREAD_NULL;
  470         p->p_csflags = CS_VALID;
  471 
  472         /*
  473          * Create credential.  This also Initializes the audit information.
  474          * XXX It is not clear what the initial values should be for audit ID,
  475          * XXX session ID, etc..
  476          */
  477         bsd_init_kprintf("calling bzero\n");
  478         bzero(&temp_cred, sizeof(temp_cred));
  479         temp_cred.cr_ngroups = 1;
  480 
  481         bsd_init_kprintf("calling kauth_cred_create\n");
  482         p->p_ucred = kauth_cred_create(&temp_cred); 
  483 
  484         /* give the (already exisiting) initial thread a reference on it */
  485         bsd_init_kprintf("calling kauth_cred_ref\n");
  486         kauth_cred_ref(p->p_ucred);
  487         ut->uu_context.vc_ucred = p->p_ucred;
  488         ut->uu_context.vc_thread = current_thread();
  489 
  490         TAILQ_INIT(&p->aio_activeq);
  491         TAILQ_INIT(&p->aio_doneq);
  492         p->aio_active_count = 0;
  493         p->aio_done_count = 0;
  494 
  495         bsd_init_kprintf("calling file_lock_init\n");
  496         file_lock_init();
  497 
  498 #if CONFIG_MACF
  499         mac_cred_label_associate_kernel(p->p_ucred);
  500         mac_task_label_update_cred (p->p_ucred, (struct task *) p->task);
  501 #endif
  502 
  503         /* Create the file descriptor table. */
  504         filedesc0.fd_refcnt = 1+1;      /* +1 so shutdown will not _FREE_ZONE */
  505         p->p_fd = &filedesc0;
  506         filedesc0.fd_cmask = cmask;
  507         filedesc0.fd_knlistsize = -1;
  508         filedesc0.fd_knlist = NULL;
  509         filedesc0.fd_knhash = NULL;
  510         filedesc0.fd_knhashmask = 0;
  511 
  512         /* Create the limits structures. */
  513         p->p_limit = &limit0;
  514         for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
  515                 limit0.pl_rlimit[i].rlim_cur = 
  516                         limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
  517         limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
  518         limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = maxprocperuid;
  519         limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
  520         limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack;
  521         limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data;
  522         limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core;
  523         limit0.pl_refcnt = 1;
  524 
  525         p->p_stats = &pstats0;
  526         p->p_sigacts = &sigacts0;
  527 
  528         /*
  529          * Charge root for two  processes: init and mach_init.
  530          */
  531         bsd_init_kprintf("calling chgproccnt\n");
  532         (void)chgproccnt(0, 1);
  533 
  534         /*
  535          *      Allocate a kernel submap for pageable memory
  536          *      for temporary copying (execve()).
  537          */
  538         {
  539                 vm_offset_t     minimum;
  540 
  541                 bsd_init_kprintf("calling kmem_suballoc\n");
  542                 ret = kmem_suballoc(kernel_map,
  543                                 &minimum,
  544                                 (vm_size_t)BSD_PAGABLE_MAP_SIZE,
  545                                 TRUE,
  546                                 VM_FLAGS_ANYWHERE,
  547                                 &bsd_pageable_map);
  548                 if (ret != KERN_SUCCESS) 
  549                         panic("bsd_init: Failed to allocate bsd pageable map");
  550         }
  551 
  552         /*
  553          * Initialize buffers and hash links for buffers
  554          *
  555          * SIDE EFFECT: Starts a thread for bcleanbuf_thread(), so must
  556          *              happen after a credential has been associated with
  557          *              the kernel task.
  558          */
  559         bsd_init_kprintf("calling bsd_bufferinit\n");
  560         bsd_bufferinit();
  561 
  562         /* Initialize the execve() semaphore */
  563         bsd_init_kprintf("calling semaphore_create\n");
  564         ret = semaphore_create(kernel_task, &execve_semaphore,
  565                                SYNC_POLICY_FIFO, BSD_SIMUL_EXECS -1);
  566         if (ret != KERN_SUCCESS)
  567                 panic("bsd_init: Failed to create execve semaphore");
  568 
  569         /*
  570          * Initialize the calendar.
  571          */
  572         IOKitInitializeTime();
  573 
  574         if (turn_on_log_leaks && !new_nkdbufs)
  575                 new_nkdbufs = 200000;
  576         start_kern_tracing(new_nkdbufs);
  577         if (turn_on_log_leaks)
  578                 log_leaks = 1;
  579 
  580         bsd_init_kprintf("calling ubc_init\n");
  581         ubc_init();
  582 
  583         /* Initialize the file systems. */
  584         bsd_init_kprintf("calling vfsinit\n");
  585         vfsinit();
  586 
  587 #if SOCKETS
  588         /* Initialize per-CPU cache allocator */
  589         mcache_init();
  590 
  591         /* Initialize mbuf's. */
  592         bsd_init_kprintf("calling mbinit\n");
  593         mbinit();
  594 #endif /* SOCKETS */
  595 
  596         /*
  597          * Initializes security event auditing.
  598          * XXX: Should/could this occur later?
  599          */
  600 #if AUDIT
  601         bsd_init_kprintf("calling audit_init\n");
  602         audit_init();  
  603 #endif
  604 
  605         /* Initialize kqueues */
  606         bsd_init_kprintf("calling knote_init\n");
  607         knote_init();
  608 
  609 #if CONFIG_EMBEDDED
  610         /* Initialize kernel memory status notifications */
  611         bsd_init_kprintf("calling kern_memorystatus_init\n");
  612         kern_memorystatus_init();
  613 #endif
  614 
  615         /* Initialize for async IO */
  616         bsd_init_kprintf("calling aio_init\n");
  617         aio_init();
  618 
  619         /* Initialize pipes */
  620         bsd_init_kprintf("calling pipeinit\n");
  621         pipeinit();
  622 
  623         /* Initialize SysV shm subsystem locks; the subsystem proper is
  624          * initialized through a sysctl.
  625          */
  626 #if SYSV_SHM
  627         bsd_init_kprintf("calling sysv_shm_lock_init\n");
  628         sysv_shm_lock_init();
  629 #endif
  630 #if SYSV_SEM
  631         bsd_init_kprintf("calling sysv_sem_lock_init\n");
  632         sysv_sem_lock_init();
  633 #endif
  634 #if SYSV_MSG
  635         bsd_init_kprintf("sysv_msg_lock_init\n");
  636         sysv_msg_lock_init();
  637 #endif
  638         bsd_init_kprintf("calling pshm_lock_init\n");
  639         pshm_lock_init();
  640         bsd_init_kprintf("calling psem_lock_init\n");
  641         psem_lock_init();
  642 
  643         pthread_init();
  644         /* POSIX Shm and Sem */
  645         bsd_init_kprintf("calling pshm_cache_init\n");
  646         pshm_cache_init();
  647         bsd_init_kprintf("calling psem_cache_init\n");
  648         psem_cache_init();
  649         bsd_init_kprintf("calling time_zone_slock_init\n");
  650         time_zone_slock_init();
  651 
  652         /* Stack snapshot facility lock */
  653         stackshot_lock_init();
  654         /*
  655          * Initialize protocols.  Block reception of incoming packets
  656          * until everything is ready.
  657          */
  658         bsd_init_kprintf("calling sysctl_register_fixed\n");
  659         sysctl_register_fixed(); 
  660         bsd_init_kprintf("calling sysctl_mib_init\n");
  661         sysctl_mib_init();
  662 #if NETWORKING
  663         bsd_init_kprintf("calling dlil_init\n");
  664         dlil_init();
  665         bsd_init_kprintf("calling proto_kpi_init\n");
  666         proto_kpi_init();
  667 #endif /* NETWORKING */
  668 #if SOCKETS
  669         bsd_init_kprintf("calling socketinit\n");
  670         socketinit();
  671         bsd_init_kprintf("calling domaininit\n");
  672         domaininit();
  673 #endif /* SOCKETS */
  674 
  675         p->p_fd->fd_cdir = NULL;
  676         p->p_fd->fd_rdir = NULL;
  677 
  678 #ifdef GPROF
  679         /* Initialize kernel profiling. */
  680         kmstartup();
  681 #endif
  682 
  683         /* kick off timeout driven events by calling first time */
  684         thread_wakeup(&lbolt);
  685         timeout(lightning_bolt, 0, hz);
  686 
  687         bsd_init_kprintf("calling bsd_autoconf\n");
  688         bsd_autoconf();
  689 
  690 #if CONFIG_DTRACE
  691         extern void dtrace_postinit(void);
  692         dtrace_postinit();
  693 #endif
  694 
  695         /*
  696          * We attach the loopback interface *way* down here to ensure
  697          * it happens after autoconf(), otherwise it becomes the
  698          * "primary" interface.
  699          */
  700 #include <loop.h>
  701 #if NLOOP > 0
  702         bsd_init_kprintf("calling loopattach\n");
  703         loopattach();                   /* XXX */
  704 #endif
  705         
  706 #if NETHER > 0
  707         /* Register the built-in dlil ethernet interface family */
  708         bsd_init_kprintf("calling ether_family_init\n");
  709         ether_family_init();
  710 #endif /* ETHER */
  711 
  712 #if NETWORKING
  713         /* Call any kext code that wants to run just after network init */
  714         bsd_init_kprintf("calling net_init_run\n");
  715         net_init_run();
  716 #endif /* NETWORKING */
  717 
  718         bsd_init_kprintf("calling vnode_pager_bootstrap\n");
  719         vnode_pager_bootstrap();
  720 #if 0
  721         /* XXX Hack for early debug stop */
  722         printf("\nabout to sleep for 10 seconds\n");
  723         IOSleep( 10 * 1000 );
  724         /* Debugger("hello"); */
  725 #endif
  726 
  727         bsd_init_kprintf("calling inittodr\n");
  728         inittodr(0);
  729 
  730 #if CONFIG_EMBEDDED
  731         {
  732                 /* print out early VM statistics */
  733                 kern_return_t kr1;
  734                 vm_statistics_data_t stat;
  735                 mach_msg_type_number_t count;
  736 
  737                 count = HOST_VM_INFO_COUNT;
  738                 kr1 = host_statistics(host_self(),
  739                                       HOST_VM_INFO,
  740                                       (host_info_t)&stat,
  741                                       &count);
  742                 kprintf("Mach Virtual Memory Statistics (page size of 4096) bytes\n"
  743                         "Pages free:\t\t\t%u.\n"
  744                         "Pages active:\t\t\t%u.\n"
  745                         "Pages inactive:\t\t\t%u.\n"
  746                         "Pages wired down:\t\t%u.\n"
  747                         "\"Translation faults\":\t\t%u.\n"
  748                         "Pages copy-on-write:\t\t%u.\n"
  749                         "Pages zero filled:\t\t%u.\n"
  750                         "Pages reactivated:\t\t%u.\n"
  751                         "Pageins:\t\t\t%u.\n"
  752                         "Pageouts:\t\t\t\%u.\n"
  753                         "Object cache: %u hits of %u lookups (%d%% hit rate)\n",
  754 
  755                         stat.free_count,
  756                         stat.active_count,
  757                         stat.inactive_count,
  758                         stat.wire_count,
  759                         stat.faults,
  760                         stat.cow_faults,
  761                         stat.zero_fill_count,
  762                         stat.reactivations,
  763                         stat.pageins,
  764                         stat.pageouts,
  765                         stat.hits,
  766                         stat.lookups,
  767                         (stat.hits == 0) ? 100 :
  768                                            ((stat.lookups * 100) / stat.hits));
  769         }
  770 #endif /* CONFIG_EMBEDDED */
  771         
  772         /* Mount the root file system. */
  773         while( TRUE) {
  774                 int err;
  775 
  776                 bsd_init_kprintf("calling setconf\n");
  777                 setconf();
  778 
  779                 bsd_init_kprintf("vfs_mountroot\n");
  780                 if (0 == (err = vfs_mountroot()))
  781                         break;
  782                 rootdevice[0] = '\0';
  783 #if NFSCLIENT
  784                 if (mountroot == netboot_mountroot) {
  785                         printf("bsd_init: netboot_mountroot failed,"
  786                                " errno = %d\n", err);
  787                         panic("bsd_init: failed to mount network root: %s", PE_boot_args());
  788                 }
  789 #endif
  790                 printf("cannot mount root, errno = %d\n", err);
  791                 boothowto |= RB_ASKNAME;
  792         }
  793 
  794         IOSecureBSDRoot(rootdevice);
  795 
  796         context.vc_thread = current_thread();
  797         context.vc_ucred = p->p_ucred;
  798         mountlist.tqh_first->mnt_flag |= MNT_ROOTFS;
  799 
  800         bsd_init_kprintf("calling VFS_ROOT\n");
  801         /* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
  802         if (VFS_ROOT(mountlist.tqh_first, &rootvnode, &context))
  803                 panic("bsd_init: cannot find root vnode: %s", PE_boot_args());
  804         rootvnode->v_flag |= VROOT;
  805         (void)vnode_ref(rootvnode);
  806         (void)vnode_put(rootvnode);
  807         filedesc0.fd_cdir = rootvnode;
  808 
  809 #if NFSCLIENT
  810         if (mountroot == netboot_mountroot) {
  811                 int err;
  812                 /* post mount setup */
  813                 if ((err = netboot_setup()) != 0) {
  814                         panic("bsd_init: NetBoot could not find root, %d: %s", err, PE_boot_args());
  815                 }
  816         }
  817 #endif
  818         
  819 
  820 #if CONFIG_IMAGEBOOT
  821         /*
  822          * See if a system disk image is present. If so, mount it and
  823          * switch the root vnode to point to it
  824          */ 
  825   
  826         if(imageboot_needed()) {
  827                 int err;
  828 
  829                 /* An image was found */
  830                 if((err = imageboot_setup())) {
  831                         /*
  832                          * this is not fatal. Keep trying to root
  833                          * off the original media
  834                          */
  835                         printf("%s: imageboot could not find root, %d\n",
  836                                 __FUNCTION__, err);
  837                 }
  838         }
  839 #endif /* CONFIG_IMAGEBOOT */
  840   
  841         microtime(&p->p_stats->p_start);        /* for compat sake */
  842         microtime(&p->p_start);
  843         p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
  844 
  845 #if DEVFS
  846         {
  847             char mounthere[] = "/dev";  /* !const because of internal casting */
  848 
  849             bsd_init_kprintf("calling devfs_kernel_mount\n");
  850             devfs_kernel_mount(mounthere);
  851         }
  852 #endif /* DEVFS */
  853         
  854         /* Initialize signal state for process 0. */
  855         bsd_init_kprintf("calling siginit\n");
  856         siginit(p);
  857 
  858         bsd_init_kprintf("calling bsd_utaskbootstrap\n");
  859         bsd_utaskbootstrap();
  860 
  861 #if __i386__
  862         /* this should be done after the root filesystem is mounted */
  863         error = set_archhandler(p, CPU_TYPE_POWERPC);
  864         if (error) /* XXX make more generic */
  865                 exec_archhandler_ppc.path[0] = 0;
  866 #endif  
  867 
  868         bsd_init_kprintf("calling mountroot_post_hook\n");
  869 
  870         /* invoke post-root-mount hook */
  871         if (mountroot_post_hook != NULL)
  872                 mountroot_post_hook();
  873 
  874 #if 0 /* not yet */
  875         IOKitJettisonKLD();
  876         consider_zone_gc();
  877 #endif
  878         
  879         bsd_init_kprintf("done\n");
  880 }
  881 
  882 /* Called with kernel funnel held */
  883 void
  884 bsdinit_task(void)
  885 {
  886         proc_t p = current_proc();
  887         struct uthread *ut;
  888         thread_t thread;
  889 
  890         process_name("init", p);
  891 
  892         ux_handler_init();
  893 
  894         thread = current_thread();
  895         (void) host_set_exception_ports(host_priv_self(),
  896                                         EXC_MASK_ALL & ~(EXC_MASK_SYSCALL |
  897                                                          EXC_MASK_MACH_SYSCALL |
  898                                                          EXC_MASK_RPC_ALERT |
  899                                                          EXC_MASK_CRASH),
  900                                         (mach_port_t)ux_exception_port,
  901                                         EXCEPTION_DEFAULT| MACH_EXCEPTION_CODES,
  902                                         0);
  903 
  904         ut = (uthread_t)get_bsdthread_info(thread);
  905 
  906         bsd_init_task = get_threadtask(thread);
  907         init_task_failure_data[0] = 0;
  908 
  909 #if CONFIG_MACF
  910         mac_cred_label_associate_user(p->p_ucred);
  911         mac_task_label_update_cred (p->p_ucred, (struct task *) p->task);
  912 #endif
  913         load_init_program(p);
  914         lock_trace = 1;
  915 }
  916 
  917 void
  918 lightning_bolt(__unused void *dummy)
  919 {                       
  920         boolean_t       funnel_state;
  921 
  922         funnel_state = thread_funnel_set(kernel_flock, TRUE);
  923 
  924         thread_wakeup(&lbolt);
  925         timeout(lightning_bolt,0,hz);
  926         klogwakeup();
  927 
  928         (void) thread_funnel_set(kernel_flock, FALSE);
  929 }
  930 
  931 kern_return_t
  932 bsd_autoconf(void)
  933 {
  934         kprintf("bsd_autoconf: calling kminit\n");
  935         kminit();
  936 
  937         /* 
  938          * Early startup for bsd pseudodevices.
  939          */
  940         {
  941             struct pseudo_init *pi;
  942         
  943             for (pi = pseudo_inits; pi->ps_func; pi++)
  944                 (*pi->ps_func) (pi->ps_count);
  945         }
  946 
  947         return( IOKitBSDInit());
  948 }
  949 
  950 
  951 #include <sys/disklabel.h>  /* for MAXPARTITIONS */
  952 
  953 static void
  954 setconf(void)
  955 {       
  956         u_int32_t       flags;
  957         kern_return_t   err;
  958 
  959         /*
  960          * calls into IOKit can generate networking registrations
  961          * which needs to be under network funnel. Right thing to do
  962          * here is to drop the funnel alltogether and regrab it afterwards
  963          */
  964         err = IOFindBSDRoot( rootdevice, &rootdev, &flags );
  965         if( err) {
  966                 printf("setconf: IOFindBSDRoot returned an error (%d);"
  967                         "setting rootdevice to 'sd0a'.\n", err); /* XXX DEBUG TEMP */
  968                 rootdev = makedev( 6, 0 );
  969                 strlcpy(rootdevice, "sd0a", sizeof(rootdevice));
  970                 flags = 0;
  971         }
  972 
  973 #if NFSCLIENT
  974         if( flags & 1 ) {
  975                 /* network device */
  976                 mountroot = netboot_mountroot;
  977         } else {
  978 #endif
  979                 /* otherwise have vfs determine root filesystem */
  980                 mountroot = NULL;
  981 #if NFSCLIENT
  982         }
  983 #endif
  984 
  985 }
  986 
  987 void
  988 bsd_utaskbootstrap(void)
  989 {
  990         thread_t thread;
  991         struct uthread *ut;
  992 
  993         thread = cloneproc(kernproc, 0);
  994         /* Hold the reference as it will be dropped during shutdown */
  995         initproc = proc_find(1);                                
  996 #if __PROC_INTERNAL_DEBUG
  997         if (initproc == PROC_NULL)
  998                 panic("bsd_utaskbootstrap: initproc not set\n");
  999 #endif
 1000         /* Set the launch time for init */
 1001         microtime(&initproc->p_start);
 1002         microtime(&initproc->p_stats->p_start); /* for compat sake */
 1003         
 1004 
 1005         ut = (struct uthread *)get_bsdthread_info(thread);
 1006         ut->uu_sigmask = 0;
 1007         act_set_astbsd(thread);
 1008         (void) thread_resume(thread);
 1009 }
 1010 
 1011 static void
 1012 parse_bsd_args(void)
 1013 {
 1014         char namep[16];
 1015         int msgbuf;
 1016 
 1017         if (PE_parse_boot_arg("-s", namep))
 1018                 boothowto |= RB_SINGLE;
 1019 
 1020         if (PE_parse_boot_arg("-b", namep))
 1021                 boothowto |= RB_NOBOOTRC;
 1022 
 1023         if (PE_parse_boot_arg("-x", namep)) /* safe boot */
 1024                 boothowto |= RB_SAFEBOOT;
 1025 
 1026         if (PE_parse_boot_arg("-l", namep)) /* leaks logging */
 1027                 turn_on_log_leaks = 1;
 1028 
 1029         PE_parse_boot_arg("srv", &srv);
 1030         PE_parse_boot_arg("ncl", &ncl);
 1031         if (PE_parse_boot_arg("nbuf", &max_nbuf_headers)) {
 1032                 customnbuf = 1;
 1033         }
 1034         PE_parse_boot_arg("kmem", &setup_kmem);
 1035         PE_parse_boot_arg("trace", &new_nkdbufs);
 1036 
 1037         if (PE_parse_boot_arg("msgbuf", &msgbuf)) {
 1038                 log_setsize(msgbuf);
 1039         }
 1040 }
 1041 
 1042 #if !NFSCLIENT
 1043 int 
 1044 netboot_root(void)
 1045 {
 1046         return(0);
 1047 }
 1048 #endif

Cache object: 8d5c8b33633b12c149a16dda4341fd14


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