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