1/* 2 * Copyright (c) 2000-2013 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 <security/audit/audit.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#include <kern/kalloc.h> 109#include <mach/mach_host.h> 110 111#include <mach/vm_param.h> 112 113#include <vm/vm_map.h> 114#include <vm/vm_kern.h> 115 116#include <sys/ux_exception.h> /* for ux_exception_port */ 117 118#include <sys/reboot.h> 119#include <mach/exception_types.h> 120#include <dev/busvar.h> /* for pseudo_inits */ 121#include <sys/kdebug.h> 122 123#include <mach/mach_types.h> 124#include <mach/vm_prot.h> 125#include <mach/semaphore.h> 126#include <mach/sync_policy.h> 127#include <kern/clock.h> 128#include <mach/kern_return.h> 129#include <mach/thread_act.h> /* for thread_resume() */ 130#include <mach/task.h> /* for task_set_exception_ports() */ 131#include <sys/ux_exception.h> /* for ux_handler() */ 132#include <sys/ubc_internal.h> /* for ubc_init() */ 133#include <sys/mcache.h> /* for mcache_init() */ 134#include <sys/mbuf.h> /* for mbinit() */ 135#include <sys/event.h> /* for knote_init() */ 136#include <sys/kern_memorystatus.h> /* for memorystatus_init() */ 137#include <sys/aio_kern.h> /* for aio_init() */ 138#include <sys/semaphore.h> /* for psem_cache_init() */ 139#include <net/dlil.h> /* for dlil_init() */ 140#include <net/kpi_protocol.h> /* for proto_kpi_init() */ 141#include <net/iptap.h> /* for iptap_init() */ 142#include <sys/pipe.h> /* for pipeinit() */ 143#include <sys/socketvar.h> /* for socketinit() */ 144#include <sys/protosw.h> /* for domaininit() */ 145#include <kern/sched_prim.h> /* for thread_wakeup() */ 146#include <net/if_ether.h> /* for ether_family_init() */ 147#include <net/if_gif.h> /* for gif_init() */ 148#include <vm/vm_protos.h> /* for vnode_pager_bootstrap() */ 149#include <miscfs/devfs/devfsdefs.h> /* for devfs_kernel_mount() */ 150#include <mach/host_priv.h> /* for host_set_exception_ports() */ 151#include <kern/host.h> /* for host_priv_self() */ 152#include <vm/vm_kern.h> /* for kmem_suballoc() */ 153#include <sys/semaphore.h> /* for psem_lock_init() */ 154#include <sys/msgbuf.h> /* for log_setsize() */ 155#include <sys/tty.h> /* for tty_init() */ 156#include <sys/proc_uuid_policy.h> /* proc_uuid_policy_init() */ 157#include <netinet/flow_divert.h> /* flow_divert_init() */ 158#include <net/if_utun.h> /* for utun_register_control() */ 159#include <net/if_ipsec.h> /* for ipsec_register_control() */ 160#include <net/net_str_id.h> /* for net_str_id_init() */ 161#include <net/netsrc.h> /* for netsrc_init() */ 162#include <net/ntstat.h> /* for nstat_init() */ 163#include <kern/assert.h> /* for assert() */ 164#include <sys/kern_overrides.h> /* for init_system_override() */ 165 166#include <net/init.h> 167 168#if CONFIG_MACF 169#include <security/mac_framework.h> 170#include <security/mac_internal.h> /* mac_init_bsd() */ 171#include <security/mac_mach_internal.h> /* mac_update_task_label() */ 172#endif 173 174#include <machine/exec.h> 175 176#if NFSCLIENT 177#include <sys/netboot.h> 178#endif 179 180#if CONFIG_IMAGEBOOT 181#include <sys/imageboot.h> 182#endif 183 184#if PFLOG 185#include <net/if_pflog.h> 186#endif 187 188#include <pexpert/pexpert.h> 189#include <machine/pal_routines.h> 190#include <console/video_console.h> 191 192void * get_user_regs(thread_t); /* XXX kludge for <machine/thread.h> */ 193void IOKitInitializeTime(void); /* XXX */ 194void IOSleep(unsigned int); /* XXX */ 195void loopattach(void); /* XXX */ 196 197const char copyright[] = 198"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\t" 199"The Regents of the University of California. " 200"All rights reserved.\n\n"; 201 202/* Components of the first process -- never freed. */ 203struct proc proc0; 204struct session session0; 205struct pgrp pgrp0; 206struct filedesc filedesc0; 207struct plimit limit0; 208struct pstats pstats0; 209struct sigacts sigacts0; 210proc_t kernproc; 211proc_t initproc; 212 213long tk_cancc; 214long tk_nin; 215long tk_nout; 216long tk_rawcc; 217 218int lock_trace = 0; 219/* Global variables to make pstat happy. We do swapping differently */ 220int nswdev, nswap; 221int nswapmap; 222void *swapmap; 223struct swdevt swdevt[1]; 224 225dev_t rootdev; /* device of the root */ 226dev_t dumpdev; /* device to take dumps on */ 227long dumplo; /* offset into dumpdev */ 228long hostid; 229char hostname[MAXHOSTNAMELEN]; 230int hostnamelen; 231char domainname[MAXDOMNAMELEN]; 232int domainnamelen; 233 234char rootdevice[16]; /* hfs device names have at least 9 chars */ 235 236#if KMEMSTATS 237struct kmemstats kmemstats[M_LAST]; 238#endif 239 240struct vnode *rootvp; 241int boothowto = RB_DEBUG; 242 243extern kern_return_t IOFindBSDRoot(char *, unsigned int, dev_t *, u_int32_t *); 244extern void IOSecureBSDRoot(const char * rootName); 245extern kern_return_t IOKitBSDInit(void ); 246extern void kminit(void); 247extern void file_lock_init(void); 248extern void kmeminit(void); 249extern void bsd_bufferinit(void); 250extern void throttle_init(void); 251 252extern int serverperfmode; 253extern int ncl; 254 255vm_map_t bsd_pageable_map; 256vm_map_t mb_map; 257 258static int bsd_simul_execs; 259static int bsd_pageable_map_size; 260__private_extern__ int execargs_cache_size = 0; 261__private_extern__ int execargs_free_count = 0; 262__private_extern__ vm_offset_t * execargs_cache = NULL; 263 264void bsd_exec_setup(int); 265 266__private_extern__ int bootarg_vnode_cache_defeat = 0; 267 268/* 269 * Prevent kernel-based ASLR from being used, for testing. 270 */ 271#if DEVELOPMENT || DEBUG 272__private_extern__ int bootarg_disable_aslr = 0; 273#endif 274 275int cmask = CMASK; 276extern int customnbuf; 277 278void bsd_init(void); 279kern_return_t bsd_autoconf(void); 280void bsd_utaskbootstrap(void); 281 282static void parse_bsd_args(void); 283extern task_t bsd_init_task; 284extern char init_task_failure_data[]; 285extern void time_zone_slock_init(void); 286extern void select_wait_queue_init(void); 287static void process_name(const char *, proc_t); 288 289static void setconf(void); 290 291funnel_t *kernel_flock; 292 293#if SYSV_SHM 294extern void sysv_shm_lock_init(void); 295#endif 296#if SYSV_SEM 297extern void sysv_sem_lock_init(void); 298#endif 299#if SYSV_MSG 300extern void sysv_msg_lock_init(void); 301#endif 302 303#if !defined(SECURE_KERNEL) 304/* kmem access not enabled by default; can be changed with boot-args */ 305/* We don't need to keep this symbol around in RELEASE kernel */ 306int setup_kmem = 0; 307#endif 308 309#if CONFIG_MACF 310#if defined (__i386__) || defined (__x86_64__) 311/* MACF policy_check configuration flags; see policy_check.c for details */ 312int policy_check_flags = 0; 313 314extern int check_policy_init(int); 315#endif 316#endif /* CONFIG_MACF */ 317 318/* If we are using CONFIG_DTRACE */ 319#if CONFIG_DTRACE 320 extern void dtrace_postinit(void); 321#endif 322 323/* 324 * Initialization code. 325 * Called from cold start routine as 326 * soon as a stack and segmentation 327 * have been established. 328 * Functions: 329 * turn on clock 330 * hand craft 0th process 331 * call all initialization routines 332 * hand craft 1st user process 333 */ 334 335/* 336 * Sets the name for the given task. 337 */ 338static void 339process_name(const char *s, proc_t p) 340{ 341 size_t length = strlen(s); 342 343 bcopy(s, p->p_comm, 344 length >= sizeof(p->p_comm) ? sizeof(p->p_comm) : 345 length + 1); 346} 347 348/* To allow these values to be patched, they're globals here */ 349#include <machine/vmparam.h> 350struct rlimit vm_initial_limit_stack = { DFLSSIZ, MAXSSIZ - PAGE_SIZE }; 351struct rlimit vm_initial_limit_data = { DFLDSIZ, MAXDSIZ }; 352struct rlimit vm_initial_limit_core = { DFLCSIZ, MAXCSIZ }; 353 354extern thread_t cloneproc(task_t, proc_t, int, int); 355extern int (*mountroot)(void); 356 357lck_grp_t * proc_lck_grp; 358lck_grp_t * proc_slock_grp; 359lck_grp_t * proc_fdmlock_grp; 360lck_grp_t * proc_mlock_grp; 361lck_grp_attr_t * proc_lck_grp_attr; 362lck_attr_t * proc_lck_attr; 363lck_mtx_t * proc_list_mlock; 364lck_mtx_t * proc_klist_mlock; 365 366extern lck_mtx_t * execargs_cache_lock; 367 368/* hook called after root is mounted XXX temporary hack */ 369void (*mountroot_post_hook)(void); 370void (*unmountroot_pre_hook)(void); 371 372/* 373 * This function is called very early on in the Mach startup, from the 374 * function start_kernel_threads() in osfmk/kern/startup.c. It's called 375 * in the context of the current (startup) task using a call to the 376 * function kernel_thread_create() to jump into start_kernel_threads(). 377 * Internally, kernel_thread_create() calls thread_create_internal(), 378 * which calls uthread_alloc(). The function of uthread_alloc() is 379 * normally to allocate a uthread structure, and fill out the uu_sigmask, 380 * uu_context fields. It skips filling these out in the case of the "task" 381 * being "kernel_task", because the order of operation is inverted. To 382 * account for that, we need to manually fill in at least the contents 383 * of the uu_context.vc_ucred field so that the uthread structure can be 384 * used like any other. 385 */ 386 387extern void IOServicePublishResource(const char *, boolean_t); 388 389void 390bsd_init(void) 391{ 392 struct uthread *ut; 393 unsigned int i; 394 struct vfs_context context; 395 kern_return_t ret; 396 struct ucred temp_cred; 397 struct posix_cred temp_pcred; 398#if NFSCLIENT || CONFIG_IMAGEBOOT 399 boolean_t netboot = FALSE; 400#endif 401 402#define bsd_init_kprintf(x...) /* kprintf("bsd_init: " x) */ 403 404 throttle_init(); 405 406 kernel_flock = funnel_alloc(KERNEL_FUNNEL); 407 if (kernel_flock == (funnel_t *)0 ) { 408 panic("bsd_init: Failed to allocate kernel funnel"); 409 } 410 411 printf(copyright); 412 413 bsd_init_kprintf("calling kmeminit\n"); 414 kmeminit(); 415 416 bsd_init_kprintf("calling parse_bsd_args\n"); 417 parse_bsd_args(); 418 419 /* Initialize kauth subsystem before instancing the first credential */ 420 bsd_init_kprintf("calling kauth_init\n"); 421 kauth_init(); 422 423 /* Initialize process and pgrp structures. */ 424 bsd_init_kprintf("calling procinit\n"); 425 procinit(); 426 427 /* Initialize the ttys (MUST be before kminit()/bsd_autoconf()!)*/ 428 tty_init(); 429 430 kernproc = &proc0; /* implicitly bzero'ed */ 431 432 /* kernel_task->proc = kernproc; */ 433 set_bsdtask_info(kernel_task,(void *)kernproc); 434 435 /* give kernproc a name */ 436 bsd_init_kprintf("calling process_name\n"); 437 process_name("kernel_task", kernproc); 438 439 /* allocate proc lock group attribute and group */ 440 bsd_init_kprintf("calling lck_grp_attr_alloc_init\n"); 441 proc_lck_grp_attr= lck_grp_attr_alloc_init(); 442 443 proc_lck_grp = lck_grp_alloc_init("proc", proc_lck_grp_attr); 444#if CONFIG_FINE_LOCK_GROUPS 445 proc_slock_grp = lck_grp_alloc_init("proc-slock", proc_lck_grp_attr); 446 proc_fdmlock_grp = lck_grp_alloc_init("proc-fdmlock", proc_lck_grp_attr); 447 proc_mlock_grp = lck_grp_alloc_init("proc-mlock", proc_lck_grp_attr); 448#endif 449 /* Allocate proc lock attribute */ 450 proc_lck_attr = lck_attr_alloc_init(); 451#if 0 452#if __PROC_INTERNAL_DEBUG 453 lck_attr_setdebug(proc_lck_attr); 454#endif 455#endif 456 457#if CONFIG_FINE_LOCK_GROUPS 458 proc_list_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); 459 proc_klist_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); 460 lck_mtx_init(&kernproc->p_mlock, proc_mlock_grp, proc_lck_attr); 461 lck_mtx_init(&kernproc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); 462 lck_spin_init(&kernproc->p_slock, proc_slock_grp, proc_lck_attr); 463#else 464 proc_list_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); 465 proc_klist_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); 466 lck_mtx_init(&kernproc->p_mlock, proc_lck_grp, proc_lck_attr); 467 lck_mtx_init(&kernproc->p_fdmlock, proc_lck_grp, proc_lck_attr); 468 lck_spin_init(&kernproc->p_slock, proc_lck_grp, proc_lck_attr); 469#endif 470 471 assert(bsd_simul_execs != 0); 472 execargs_cache_lock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); 473 execargs_cache_size = bsd_simul_execs; 474 execargs_free_count = bsd_simul_execs; 475 execargs_cache = (vm_offset_t *)kalloc(bsd_simul_execs * sizeof(vm_offset_t)); 476 bzero(execargs_cache, bsd_simul_execs * sizeof(vm_offset_t)); 477 478 if (current_task() != kernel_task) 479 printf("bsd_init: We have a problem, " 480 "current task is not kernel task\n"); 481 482 bsd_init_kprintf("calling get_bsdthread_info\n"); 483 ut = (uthread_t)get_bsdthread_info(current_thread()); 484 485#if CONFIG_MACF 486 /* 487 * Initialize the MAC Framework 488 */ 489 mac_policy_initbsd(); 490 kernproc->p_mac_enforce = 0; 491 492#if defined (__i386__) || defined (__x86_64__) 493 /* 494 * We currently only support this on i386/x86_64, as that is the 495 * only lock code we have instrumented so far. 496 */ 497 check_policy_init(policy_check_flags); 498#endif 499#endif /* MAC */ 500 501 /* Initialize System Override call */ 502 init_system_override(); 503 504 /* 505 * Create process 0. 506 */ 507 proc_list_lock(); 508 LIST_INSERT_HEAD(&allproc, kernproc, p_list); 509 kernproc->p_pgrp = &pgrp0; 510 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 511 LIST_INIT(&pgrp0.pg_members); 512#ifdef CONFIG_FINE_LOCK_GROUPS 513 lck_mtx_init(&pgrp0.pg_mlock, proc_mlock_grp, proc_lck_attr); 514#else 515 lck_mtx_init(&pgrp0.pg_mlock, proc_lck_grp, proc_lck_attr); 516#endif 517 /* There is no other bsd thread this point and is safe without pgrp lock */ 518 LIST_INSERT_HEAD(&pgrp0.pg_members, kernproc, p_pglist); 519 kernproc->p_listflag |= P_LIST_INPGRP; 520 kernproc->p_pgrpid = 0; 521 kernproc->p_uniqueid = 0; 522 523 pgrp0.pg_session = &session0; 524 pgrp0.pg_membercnt = 1; 525 526 session0.s_count = 1; 527 session0.s_leader = kernproc; 528 session0.s_listflags = 0; 529#ifdef CONFIG_FINE_LOCK_GROUPS 530 lck_mtx_init(&session0.s_mlock, proc_mlock_grp, proc_lck_attr); 531#else 532 lck_mtx_init(&session0.s_mlock, proc_lck_grp, proc_lck_attr); 533#endif 534 LIST_INSERT_HEAD(SESSHASH(0), &session0, s_hash); 535 proc_list_unlock(); 536 537#if CONFIG_LCTX 538 kernproc->p_lctx = NULL; 539#endif 540 541 kernproc->task = kernel_task; 542 543 kernproc->p_stat = SRUN; 544 kernproc->p_flag = P_SYSTEM; 545 kernproc->p_lflag = 0; 546 kernproc->p_ladvflag = 0; 547 548#if DEVELOPMENT || DEBUG 549 if (bootarg_disable_aslr) 550 kernproc->p_flag |= P_DISABLE_ASLR; 551#endif 552 553 kernproc->p_nice = NZERO; 554 kernproc->p_pptr = kernproc; 555 556 TAILQ_INIT(&kernproc->p_uthlist); 557 TAILQ_INSERT_TAIL(&kernproc->p_uthlist, ut, uu_list); 558 559 kernproc->sigwait = FALSE; 560 kernproc->sigwait_thread = THREAD_NULL; 561 kernproc->exit_thread = THREAD_NULL; 562 kernproc->p_csflags = CS_VALID; 563 564 /* 565 * Create credential. This also Initializes the audit information. 566 */ 567 bsd_init_kprintf("calling bzero\n"); 568 bzero(&temp_cred, sizeof(temp_cred)); 569 bzero(&temp_pcred, sizeof(temp_pcred)); 570 temp_pcred.cr_ngroups = 1; 571 /* kern_proc, shouldn't call up to DS for group membership */ 572 temp_pcred.cr_flags = CRF_NOMEMBERD; 573 temp_cred.cr_audit.as_aia_p = audit_default_aia_p; 574 575 bsd_init_kprintf("calling kauth_cred_create\n"); 576 /* 577 * We have to label the temp cred before we create from it to 578 * properly set cr_ngroups, or the create will fail. 579 */ 580 posix_cred_label(&temp_cred, &temp_pcred); 581 kernproc->p_ucred = kauth_cred_create(&temp_cred); 582 583 /* update cred on proc */ 584 PROC_UPDATE_CREDS_ONPROC(kernproc); 585 586 /* give the (already exisiting) initial thread a reference on it */ 587 bsd_init_kprintf("calling kauth_cred_ref\n"); 588 kauth_cred_ref(kernproc->p_ucred); 589 ut->uu_context.vc_ucred = kernproc->p_ucred; 590 ut->uu_context.vc_thread = current_thread(); 591 592 TAILQ_INIT(&kernproc->p_aio_activeq); 593 TAILQ_INIT(&kernproc->p_aio_doneq); 594 kernproc->p_aio_total_count = 0; 595 kernproc->p_aio_active_count = 0; 596 597 bsd_init_kprintf("calling file_lock_init\n"); 598 file_lock_init(); 599 600#if CONFIG_MACF 601 mac_cred_label_associate_kernel(kernproc->p_ucred); 602 mac_task_label_update_cred (kernproc->p_ucred, (struct task *) kernproc->task); 603#endif 604 605 /* Create the file descriptor table. */ 606 kernproc->p_fd = &filedesc0; 607 filedesc0.fd_cmask = cmask; 608 filedesc0.fd_knlistsize = -1; 609 filedesc0.fd_knlist = NULL; 610 filedesc0.fd_knhash = NULL; 611 filedesc0.fd_knhashmask = 0; 612 613 /* Create the limits structures. */ 614 kernproc->p_limit = &limit0; 615 for (i = 0; i < sizeof(kernproc->p_rlimit)/sizeof(kernproc->p_rlimit[0]); i++) 616 limit0.pl_rlimit[i].rlim_cur = 617 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 618 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 619 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = maxprocperuid; 620 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; 621 limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack; 622 limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data; 623 limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core; 624 limit0.pl_refcnt = 1; 625 626 kernproc->p_stats = &pstats0; 627 kernproc->p_sigacts = &sigacts0; 628 629 /* 630 * Charge root for two processes: init and mach_init. 631 */ 632 bsd_init_kprintf("calling chgproccnt\n"); 633 (void)chgproccnt(0, 1); 634 635 /* 636 * Allocate a kernel submap for pageable memory 637 * for temporary copying (execve()). 638 */ 639 { 640 vm_offset_t minimum; 641 642 bsd_init_kprintf("calling kmem_suballoc\n"); 643 assert(bsd_pageable_map_size != 0); 644 ret = kmem_suballoc(kernel_map, 645 &minimum, 646 (vm_size_t)bsd_pageable_map_size, 647 TRUE, 648 VM_FLAGS_ANYWHERE, 649 &bsd_pageable_map); 650 if (ret != KERN_SUCCESS) 651 panic("bsd_init: Failed to allocate bsd pageable map"); 652 } 653 654 /* 655 * Initialize buffers and hash links for buffers 656 * 657 * SIDE EFFECT: Starts a thread for bcleanbuf_thread(), so must 658 * happen after a credential has been associated with 659 * the kernel task. 660 */ 661 bsd_init_kprintf("calling bsd_bufferinit\n"); 662 bsd_bufferinit(); 663 664 /* Initialize the execve() semaphore */ 665 bsd_init_kprintf("calling semaphore_create\n"); 666 667 if (ret != KERN_SUCCESS) 668 panic("bsd_init: Failed to create execve semaphore"); 669 670 /* 671 * Initialize the calendar. 672 */ 673 bsd_init_kprintf("calling IOKitInitializeTime\n"); 674 IOKitInitializeTime(); 675 676 bsd_init_kprintf("calling ubc_init\n"); 677 ubc_init(); 678 679 /* 680 * Initialize device-switches. 681 */ 682 bsd_init_kprintf("calling devsw_init() \n"); 683 devsw_init(); 684 685 /* Initialize the file systems. */ 686 bsd_init_kprintf("calling vfsinit\n"); 687 vfsinit(); 688 689#if CONFIG_PROC_UUID_POLICY 690 /* Initial proc_uuid_policy subsystem */ 691 bsd_init_kprintf("calling proc_uuid_policy_init()\n"); 692 proc_uuid_policy_init(); 693#endif 694 695#if SOCKETS 696 /* Initialize per-CPU cache allocator */ 697 mcache_init(); 698 699 /* Initialize mbuf's. */ 700 bsd_init_kprintf("calling mbinit\n"); 701 mbinit(); 702 net_str_id_init(); /* for mbuf tags */ 703#endif /* SOCKETS */ 704 705 /* 706 * Initializes security event auditing. 707 * XXX: Should/could this occur later? 708 */ 709#if CONFIG_AUDIT 710 bsd_init_kprintf("calling audit_init\n"); 711 audit_init(); 712#endif 713 714 /* Initialize kqueues */ 715 bsd_init_kprintf("calling knote_init\n"); 716 knote_init(); 717 718 /* Initialize for async IO */ 719 bsd_init_kprintf("calling aio_init\n"); 720 aio_init(); 721 722 /* Initialize pipes */ 723 bsd_init_kprintf("calling pipeinit\n"); 724 pipeinit(); 725 726 /* Initialize SysV shm subsystem locks; the subsystem proper is 727 * initialized through a sysctl. 728 */ 729#if SYSV_SHM 730 bsd_init_kprintf("calling sysv_shm_lock_init\n"); 731 sysv_shm_lock_init(); 732#endif 733#if SYSV_SEM 734 bsd_init_kprintf("calling sysv_sem_lock_init\n"); 735 sysv_sem_lock_init(); 736#endif 737#if SYSV_MSG 738 bsd_init_kprintf("sysv_msg_lock_init\n"); 739 sysv_msg_lock_init(); 740#endif 741 bsd_init_kprintf("calling pshm_lock_init\n"); 742 pshm_lock_init(); 743 bsd_init_kprintf("calling psem_lock_init\n"); 744 psem_lock_init(); 745 746 pthread_init(); 747 /* POSIX Shm and Sem */ 748 bsd_init_kprintf("calling pshm_cache_init\n"); 749 pshm_cache_init(); 750 bsd_init_kprintf("calling psem_cache_init\n"); 751 psem_cache_init(); 752 bsd_init_kprintf("calling time_zone_slock_init\n"); 753 time_zone_slock_init(); 754 bsd_init_kprintf("calling select_wait_queue_init\n"); 755 select_wait_queue_init(); 756 757 /* 758 * Initialize protocols. Block reception of incoming packets 759 * until everything is ready. 760 */ 761 bsd_init_kprintf("calling sysctl_register_fixed\n"); 762 sysctl_register_fixed(); 763 bsd_init_kprintf("calling sysctl_mib_init\n"); 764 sysctl_mib_init(); 765#if NETWORKING 766 bsd_init_kprintf("calling dlil_init\n"); 767 dlil_init(); 768 bsd_init_kprintf("calling proto_kpi_init\n"); 769 proto_kpi_init(); 770#endif /* NETWORKING */ 771#if SOCKETS 772 bsd_init_kprintf("calling socketinit\n"); 773 socketinit(); 774 bsd_init_kprintf("calling domaininit\n"); 775 domaininit(); 776 iptap_init(); 777#if FLOW_DIVERT 778 flow_divert_init(); 779#endif /* FLOW_DIVERT */ 780#endif /* SOCKETS */ 781 782 kernproc->p_fd->fd_cdir = NULL; 783 kernproc->p_fd->fd_rdir = NULL; 784 785#if CONFIG_FREEZE 786#ifndef CONFIG_MEMORYSTATUS 787 #error "CONFIG_FREEZE defined without matching CONFIG_MEMORYSTATUS" 788#endif 789 /* Initialise background freezing */ 790 bsd_init_kprintf("calling memorystatus_freeze_init\n"); 791 memorystatus_freeze_init(); 792#endif 793 794#if CONFIG_MEMORYSTATUS 795 /* Initialize kernel memory status notifications */ 796 bsd_init_kprintf("calling memorystatus_init\n"); 797 memorystatus_init(); 798#endif /* CONFIG_MEMORYSTATUS */ 799 800#ifdef GPROF 801 /* Initialize kernel profiling. */ 802 kmstartup(); 803#endif 804 805 bsd_init_kprintf("calling bsd_autoconf\n"); 806 bsd_autoconf(); 807 808#if CONFIG_DTRACE 809 dtrace_postinit(); 810#endif 811 812 /* 813 * We attach the loopback interface *way* down here to ensure 814 * it happens after autoconf(), otherwise it becomes the 815 * "primary" interface. 816 */ 817#include <loop.h> 818#if NLOOP > 0 819 bsd_init_kprintf("calling loopattach\n"); 820 loopattach(); /* XXX */ 821#endif 822#if NGIF 823 /* Initialize gif interface (after lo0) */ 824 gif_init(); 825#endif 826 827#if PFLOG 828 /* Initialize packet filter log interface */ 829 pfloginit(); 830#endif /* PFLOG */ 831 832#if NETHER > 0 833 /* Register the built-in dlil ethernet interface family */ 834 bsd_init_kprintf("calling ether_family_init\n"); 835 ether_family_init(); 836#endif /* ETHER */ 837 838#if NETWORKING 839 /* Call any kext code that wants to run just after network init */ 840 bsd_init_kprintf("calling net_init_run\n"); 841 net_init_run(); 842 843 /* register user tunnel kernel control handler */ 844 utun_register_control(); 845#if IPSEC 846 ipsec_register_control(); 847#endif /* IPSEC */ 848 netsrc_init(); 849 nstat_init(); 850#endif /* NETWORKING */ 851 852 bsd_init_kprintf("calling vnode_pager_bootstrap\n"); 853 vnode_pager_bootstrap(); 854#if 0 855 /* XXX Hack for early debug stop */ 856 printf("\nabout to sleep for 10 seconds\n"); 857 IOSleep( 10 * 1000 ); 858 /* Debugger("hello"); */ 859#endif 860 861 bsd_init_kprintf("calling inittodr\n"); 862 inittodr(0); 863 864 /* Mount the root file system. */ 865 while( TRUE) { 866 int err; 867 868 bsd_init_kprintf("calling setconf\n"); 869 setconf(); 870#if NFSCLIENT 871 netboot = (mountroot == netboot_mountroot); 872#endif 873 874 bsd_init_kprintf("vfs_mountroot\n"); 875 if (0 == (err = vfs_mountroot())) 876 break; 877 rootdevice[0] = '\0'; 878#if NFSCLIENT 879 if (netboot) { 880 PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ 881 vc_progress_set(FALSE, 0); 882 for (i=1; 1; i*=2) { 883 printf("bsd_init: failed to mount network root, error %d, %s\n", 884 err, PE_boot_args()); 885 printf("We are hanging here...\n"); 886 IOSleep(i*60*1000); 887 } 888 /*NOTREACHED*/ 889 } 890#endif 891 printf("cannot mount root, errno = %d\n", err); 892 boothowto |= RB_ASKNAME; 893 } 894 895 IOSecureBSDRoot(rootdevice); 896 897 context.vc_thread = current_thread(); 898 context.vc_ucred = kernproc->p_ucred; 899 mountlist.tqh_first->mnt_flag |= MNT_ROOTFS; 900 901 bsd_init_kprintf("calling VFS_ROOT\n"); 902 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ 903 if (VFS_ROOT(mountlist.tqh_first, &rootvnode, &context)) 904 panic("bsd_init: cannot find root vnode: %s", PE_boot_args()); 905 rootvnode->v_flag |= VROOT; 906 (void)vnode_ref(rootvnode); 907 (void)vnode_put(rootvnode); 908 filedesc0.fd_cdir = rootvnode; 909 910#if NFSCLIENT 911 if (netboot) { 912 int err; 913 914 netboot = TRUE; 915 /* post mount setup */ 916 if ((err = netboot_setup()) != 0) { 917 PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ 918 vc_progress_set(FALSE, 0); 919 for (i=1; 1; i*=2) { 920 printf("bsd_init: NetBoot could not find root, error %d: %s\n", 921 err, PE_boot_args()); 922 printf("We are hanging here...\n"); 923 IOSleep(i*60*1000); 924 } 925 /*NOTREACHED*/ 926 } 927 } 928#endif 929 930 931#if CONFIG_IMAGEBOOT 932 /* 933 * See if a system disk image is present. If so, mount it and 934 * switch the root vnode to point to it 935 */ 936 if (netboot == FALSE && imageboot_needed()) { 937 /* 938 * An image was found. No turning back: we're booted 939 * with a kernel from the disk image. 940 */ 941 imageboot_setup(); 942 } 943#endif /* CONFIG_IMAGEBOOT */ 944 945 /* set initial time; all other resource data is already zero'ed */ 946 microtime_with_abstime(&kernproc->p_start, &kernproc->p_stats->ps_start); 947 948#if DEVFS 949 { 950 char mounthere[] = "/dev"; /* !const because of internal casting */ 951 952 bsd_init_kprintf("calling devfs_kernel_mount\n"); 953 devfs_kernel_mount(mounthere); 954 } 955#endif /* DEVFS */ 956 957 /* Initialize signal state for process 0. */ 958 bsd_init_kprintf("calling siginit\n"); 959 siginit(kernproc); 960 961 bsd_init_kprintf("calling bsd_utaskbootstrap\n"); 962 bsd_utaskbootstrap(); 963 964#if defined(__LP64__) 965 kernproc->p_flag |= P_LP64; 966#endif 967 968 pal_kernel_announce(); 969 970 bsd_init_kprintf("calling mountroot_post_hook\n"); 971 972 /* invoke post-root-mount hook */ 973 if (mountroot_post_hook != NULL) 974 mountroot_post_hook(); 975 976#if 0 /* not yet */ 977 consider_zone_gc(FALSE); 978#endif 979 980 bsd_init_kprintf("done\n"); 981 982} 983 984/* Called with kernel funnel held */ 985void 986bsdinit_task(void) 987{ 988 proc_t p = current_proc(); 989 struct uthread *ut; 990 thread_t thread; 991 992 process_name("init", p); 993 994 ux_handler_init(); 995 996 thread = current_thread(); 997 (void) host_set_exception_ports(host_priv_self(), 998 EXC_MASK_ALL & ~(EXC_MASK_RPC_ALERT),//pilotfish (shark) needs this port 999 (mach_port_t) ux_exception_port, 1000 EXCEPTION_DEFAULT| MACH_EXCEPTION_CODES, 1001 0); 1002 1003 ut = (uthread_t)get_bsdthread_info(thread); 1004 1005 bsd_init_task = get_threadtask(thread); 1006 init_task_failure_data[0] = 0; 1007 1008#if CONFIG_MACF 1009 mac_cred_label_associate_user(p->p_ucred); 1010 mac_task_label_update_cred (p->p_ucred, (struct task *) p->task); 1011#endif 1012 load_init_program(p); 1013 lock_trace = 1; 1014} 1015 1016kern_return_t 1017bsd_autoconf(void) 1018{ 1019 kprintf("bsd_autoconf: calling kminit\n"); 1020 kminit(); 1021 1022 /* 1023 * Early startup for bsd pseudodevices. 1024 */ 1025 { 1026 struct pseudo_init *pi; 1027 1028 for (pi = pseudo_inits; pi->ps_func; pi++) 1029 (*pi->ps_func) (pi->ps_count); 1030 } 1031 1032 return( IOKitBSDInit()); 1033} 1034 1035 1036#include <sys/disklabel.h> /* for MAXPARTITIONS */ 1037 1038static void 1039setconf(void) 1040{ 1041 u_int32_t flags; 1042 kern_return_t err; 1043 1044 /* 1045 * calls into IOKit can generate networking registrations 1046 * which needs to be under network funnel. Right thing to do 1047 * here is to drop the funnel alltogether and regrab it afterwards 1048 */ 1049 err = IOFindBSDRoot(rootdevice, sizeof(rootdevice), &rootdev, &flags); 1050 if( err) { 1051 printf("setconf: IOFindBSDRoot returned an error (%d);" 1052 "setting rootdevice to 'sd0a'.\n", err); /* XXX DEBUG TEMP */ 1053 rootdev = makedev( 6, 0 ); 1054 strlcpy(rootdevice, "sd0a", sizeof(rootdevice)); 1055 flags = 0; 1056 } 1057 1058#if NFSCLIENT 1059 if( flags & 1 ) { 1060 /* network device */ 1061 mountroot = netboot_mountroot; 1062 } else { 1063#endif 1064 /* otherwise have vfs determine root filesystem */ 1065 mountroot = NULL; 1066#if NFSCLIENT 1067 } 1068#endif 1069 1070} 1071 1072void 1073bsd_utaskbootstrap(void) 1074{ 1075 thread_t thread; 1076 struct uthread *ut; 1077 1078 /* 1079 * Clone the bootstrap process from the kernel process, without 1080 * inheriting either task characteristics or memory from the kernel; 1081 */ 1082 thread = cloneproc(TASK_NULL, kernproc, FALSE, TRUE); 1083 1084 /* Hold the reference as it will be dropped during shutdown */ 1085 initproc = proc_find(1); 1086#if __PROC_INTERNAL_DEBUG 1087 if (initproc == PROC_NULL) 1088 panic("bsd_utaskbootstrap: initproc not set\n"); 1089#endif 1090 /* 1091 * Since we aren't going back out the normal way to our parent, 1092 * we have to drop the transition locks explicitly. 1093 */ 1094 proc_signalend(initproc, 0); 1095 proc_transend(initproc, 0); 1096 1097 ut = (struct uthread *)get_bsdthread_info(thread); 1098 ut->uu_sigmask = 0; 1099 act_set_astbsd(thread); 1100 (void) thread_resume(thread); 1101} 1102 1103static void 1104parse_bsd_args(void) 1105{ 1106 char namep[16]; 1107 int msgbuf; 1108 1109 if ( PE_parse_boot_argn("-s", namep, sizeof (namep))) 1110 boothowto |= RB_SINGLE; 1111 1112 if (PE_parse_boot_argn("-b", namep, sizeof (namep))) 1113 boothowto |= RB_NOBOOTRC; 1114 1115 if (PE_parse_boot_argn("-x", namep, sizeof (namep))) /* safe boot */ 1116 boothowto |= RB_SAFEBOOT; 1117 1118 /* disable vnode_cache_is_authorized() by setting vnode_cache_defeat */ 1119 if (PE_parse_boot_argn("-vnode_cache_defeat", namep, sizeof (namep))) 1120 bootarg_vnode_cache_defeat = 1; 1121 1122#if DEVELOPMENT || DEBUG 1123 if (PE_parse_boot_argn("-disable_aslr", namep, sizeof (namep))) 1124 bootarg_disable_aslr = 1; 1125#endif 1126 1127 PE_parse_boot_argn("ncl", &ncl, sizeof (ncl)); 1128 if (PE_parse_boot_argn("nbuf", &max_nbuf_headers, 1129 sizeof (max_nbuf_headers))) { 1130 customnbuf = 1; 1131 } 1132#if !defined(SECURE_KERNEL) 1133 PE_parse_boot_argn("kmem", &setup_kmem, sizeof (setup_kmem)); 1134#endif 1135 1136#if CONFIG_MACF 1137#if defined (__i386__) || defined (__x86_64__) 1138 PE_parse_boot_argn("policy_check", &policy_check_flags, sizeof (policy_check_flags)); 1139#endif 1140#endif /* CONFIG_MACF */ 1141 1142 if (PE_parse_boot_argn("msgbuf", &msgbuf, sizeof (msgbuf))) { 1143 log_setsize(msgbuf); 1144 } 1145 1146 if (PE_parse_boot_argn("-novfscache", namep, sizeof(namep))) { 1147 nc_disabled = 1; 1148 } 1149 1150} 1151 1152void 1153bsd_exec_setup(int scale) 1154{ 1155 1156 switch (scale) { 1157 case 0: 1158 case 1: 1159 bsd_simul_execs = BSD_SIMUL_EXECS; 1160 break; 1161 case 2: 1162 case 3: 1163 bsd_simul_execs = 65; 1164 break; 1165 case 4: 1166 case 5: 1167 bsd_simul_execs = 129; 1168 break; 1169 case 6: 1170 case 7: 1171 bsd_simul_execs = 257; 1172 break; 1173 default: 1174 bsd_simul_execs = 513; 1175 break; 1176 1177 } 1178 bsd_pageable_map_size = (bsd_simul_execs * BSD_PAGEABLE_SIZE_PER_EXEC); 1179} 1180 1181#if !NFSCLIENT 1182int 1183netboot_root(void); 1184 1185int 1186netboot_root(void) 1187{ 1188 return(0); 1189} 1190#endif 1191