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