]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/bsd_init.c
xnu-517.7.7.tar.gz
[apple/xnu.git] / bsd / kern / bsd_init.c
CommitLineData
1c79356b 1/*
55e303ae 2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
e5568f75
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
e5568f75
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
24 * The Regents of the University of California. All rights reserved.
25 * (c) UNIX System Laboratories, Inc.
26 * All or some portions of this file are derived from material licensed
27 * to the University of California by American Telephone and Telegraph
28 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
29 * the permission of UNIX System Laboratories, Inc.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * SUCH DAMAGE.
58 *
59 * @(#)init_main.c 8.16 (Berkeley) 5/14/95
60 */
61
62/*
63 *
64 * Mach Operating System
65 * Copyright (c) 1987 Carnegie-Mellon University
66 * All rights reserved. The CMU software License Agreement specifies
67 * the terms and conditions for use and redistribution.
68 */
1c79356b
A
69
70#include <sys/param.h>
71#include <sys/filedesc.h>
72#include <sys/kernel.h>
73#include <sys/mount.h>
74#include <sys/proc.h>
75#include <sys/systm.h>
76#include <sys/vnode.h>
77#include <sys/conf.h>
78#include <sys/buf.h>
79#include <sys/clist.h>
80#include <sys/user.h>
55e303ae
A
81#include <sys/time.h>
82#include <sys/systm.h>
83
e5568f75 84#include <bsm/audit_kernel.h>
1c79356b
A
85
86#include <sys/malloc.h>
87#include <sys/dkstat.h>
88
89#include <machine/spl.h>
90#include <kern/thread.h>
91#include <kern/task.h>
92#include <kern/ast.h>
93
94#include <mach/vm_param.h>
95
96#include <vm/vm_map.h>
97#include <vm/vm_kern.h>
98
55e303ae 99#include <sys/ux_exception.h> /* for ux_exception_port */
1c79356b
A
100
101#include <sys/reboot.h>
102#include <mach/exception_types.h>
55e303ae 103#include <dev/busvar.h> /* for pseudo_inits */
1c79356b
A
104#include <sys/kdebug.h>
105
765c9de3
A
106#include <mach/mach_types.h>
107#include <mach/vm_prot.h>
108#include <mach/semaphore.h>
109#include <mach/sync_policy.h>
110#include <kern/clock.h>
111#include <mach/kern_return.h>
112
9bccf70c
A
113#include <mach/shared_memory_server.h>
114#include <vm/vm_shared_memory_server.h>
115
9bccf70c 116extern int app_profile; /* on/off switch for pre-heat cache */
1c79356b
A
117
118char copyright[] =
55e303ae
A
119"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\t"
120"The Regents of the University of California. "
121"All rights reserved.\n\n";
1c79356b
A
122
123extern void ux_handler();
124
125/* Components of the first process -- never freed. */
126struct proc proc0;
127struct session session0;
128struct pgrp pgrp0;
129struct pcred cred0;
130struct filedesc filedesc0;
131struct plimit limit0;
132struct pstats pstats0;
133struct sigacts sigacts0;
134struct proc *kernproc, *initproc;
135
1c79356b
A
136long tk_cancc;
137long tk_nin;
138long tk_nout;
139long tk_rawcc;
140
141/* Global variables to make pstat happy. We do swapping differently */
142int nswdev, nswap;
143int nswapmap;
144void *swapmap;
145struct swdevt swdevt[1];
146
147dev_t rootdev; /* device of the root */
148dev_t dumpdev; /* device to take dumps on */
149long dumplo; /* offset into dumpdev */
150long hostid;
151char hostname[MAXHOSTNAMELEN];
55e303ae 152int hostnamelen;
1c79356b 153char domainname[MAXDOMNAMELEN];
55e303ae
A
154int domainnamelen;
155char classichandler[32] = {0};
156long classichandler_fsid = -1L;
157long classichandler_fileid = -1L;
1c79356b
A
158
159char rootdevice[16]; /* hfs device names have at least 9 chars */
160struct timeval boottime; /* GRODY! This has to go... */
1c79356b
A
161
162#ifdef KMEMSTATS
163struct kmemstats kmemstats[M_LAST];
164#endif
165
166int lbolt; /* awoken once a second */
167struct vnode *rootvp;
168int boothowto = RB_DEBUG;
169
55e303ae 170#define BSD_PAGABLE_MAP_SIZE (16 * 512 * 1024)
1c79356b
A
171vm_map_t bsd_pageable_map;
172vm_map_t mb_map;
765c9de3 173semaphore_t execve_semaphore;
1c79356b
A
174
175int cmask = CMASK;
176
177int parse_bsd_args(void);
178extern int bsd_hardclockinit;
9bccf70c 179extern task_t bsd_init_task;
1c79356b 180extern char init_task_failure_data[];
9bccf70c 181extern void time_zone_slock_init(void);
1c79356b 182
55e303ae
A
183funnel_t *kernel_flock;
184funnel_t *network_flock;
1c79356b
A
185int disable_funnel = 0; /* disables split funnel */
186int enable_funnel = 0; /* disables split funnel */
187
188/*
189 * Initialization code.
190 * Called from cold start routine as
191 * soon as a stack and segmentation
192 * have been established.
193 * Functions:
1c79356b
A
194 * turn on clock
195 * hand craft 0th process
196 * call all initialization routines
55e303ae 197 * hand craft 1st user process
1c79356b
A
198 */
199
200/*
201 * Sets the name for the given task.
202 */
765c9de3
A
203void
204proc_name(s, p)
1c79356b
A
205 char *s;
206 struct proc *p;
207{
208 int length = strlen(s);
209
210 bcopy(s, p->p_comm,
211 length >= sizeof(p->p_comm) ? sizeof(p->p_comm) :
212 length + 1);
213}
214
1c79356b
A
215/* To allow these values to be patched, they're globals here */
216#include <machine/vmparam.h>
217struct rlimit vm_initial_limit_stack = { DFLSSIZ, MAXSSIZ };
218struct rlimit vm_initial_limit_data = { DFLDSIZ, MAXDSIZ };
219struct rlimit vm_initial_limit_core = { DFLCSIZ, MAXCSIZ };
220
221extern thread_t first_thread;
9bccf70c
A
222extern thread_act_t cloneproc(struct proc *, int);
223extern int (*mountroot) __P((void));
224extern int netboot_mountroot(); /* netboot.c */
225extern int netboot_setup(struct proc * p);
1c79356b 226
9bccf70c
A
227/* hook called after root is mounted XXX temporary hack */
228void (*mountroot_post_hook)(void);
1c79356b
A
229
230void
231bsd_init()
232{
233 register struct proc *p;
234 extern struct ucred *rootcred;
235 register int i;
236 int s;
237 thread_t th;
1c79356b
A
238 void lightning_bolt(void );
239 kern_return_t ret;
240 boolean_t funnel_state;
241 extern void uthread_zone_init();
242
1c79356b 243
1c79356b
A
244 /* split funnel is enabled by default */
245 PE_parse_boot_arg("dfnl", &disable_funnel);
1c79356b
A
246
247 kernel_flock = funnel_alloc(KERNEL_FUNNEL);
248 if (kernel_flock == (funnel_t *)0 ) {
9bccf70c 249 panic("bsd_init: Failed to allocate kernel funnel");
1c79356b
A
250 }
251
1c79356b
A
252 funnel_state = thread_funnel_set(kernel_flock, TRUE);
253
254 if (!disable_funnel) {
255 network_flock = funnel_alloc(NETWORK_FUNNEL);
256 if (network_flock == (funnel_t *)0 ) {
9bccf70c 257 panic("bsd_init: Failed to allocate network funnel");
1c79356b
A
258 }
259 } else {
260 network_flock = kernel_flock;
261 }
262
1c79356b
A
263 printf(copyright);
264
265 kmeminit();
266
267 parse_bsd_args();
268
269 bsd_bufferinit();
270
271 /* Initialize the uthread zone */
272 uthread_zone_init();
273
274 /*
275 * Initialize process and pgrp structures.
276 */
277 procinit();
278
279 kernproc = &proc0;
280
281 p = kernproc;
282
283 /* kernel_task->proc = kernproc; */
9bccf70c 284 set_bsdtask_info(kernel_task,(void *)p);
1c79356b
A
285 p->p_pid = 0;
286
287 /* give kernproc a name */
288 proc_name("kernel_task", p);
289
290 if (current_task() != kernel_task)
9bccf70c
A
291 printf("bsd_init: We have a problem, "
292 "current task is not kernel task\n");
1c79356b
A
293
294 /*
295 * Create process 0.
296 */
297 LIST_INSERT_HEAD(&allproc, p, p_list);
298 p->p_pgrp = &pgrp0;
299 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
300 LIST_INIT(&pgrp0.pg_members);
301 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
302
303 pgrp0.pg_session = &session0;
304 session0.s_count = 1;
305 session0.s_leader = p;
306
307 p->task = kernel_task;
308
309 p->p_stat = SRUN;
310 p->p_flag = P_INMEM|P_SYSTEM;
311 p->p_nice = NZERO;
312 p->p_pptr = p;
313 lockinit(&p->signal_lock, PVM, "signal", 0, 0);
9bccf70c 314 TAILQ_INIT(&p->p_uthlist);
1c79356b
A
315 p->sigwait = FALSE;
316 p->sigwait_thread = THREAD_NULL;
317 p->exit_thread = THREAD_NULL;
318
319 /* Create credentials. */
320 lockinit(&cred0.pc_lock, PLOCK, "proc0 cred", 0, 0);
321 cred0.p_refcnt = 1;
322 p->p_cred = &cred0;
323 p->p_ucred = crget();
324 p->p_ucred->cr_ngroups = 1; /* group 0 */
55e303ae
A
325
326 TAILQ_INIT(&p->aio_activeq);
327 TAILQ_INIT(&p->aio_doneq);
328 p->aio_active_count = 0;
329 p->aio_done_count = 0;
330
331 /* Set the audit info for this process */
332 audit_proc_init(p);
1c79356b
A
333
334 /* Create the file descriptor table. */
335 filedesc0.fd_refcnt = 1+1; /* +1 so shutdown will not _FREE_ZONE */
336 p->p_fd = &filedesc0;
337 filedesc0.fd_cmask = cmask;
55e303ae
A
338 filedesc0.fd_knlistsize = -1;
339 filedesc0.fd_knlist = NULL;
340 filedesc0.fd_knhash = NULL;
341 filedesc0.fd_knhashmask = 0;
1c79356b
A
342
343 /* Create the limits structures. */
344 p->p_limit = &limit0;
345 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
346 limit0.pl_rlimit[i].rlim_cur =
347 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
348 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
349 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
55e303ae 350 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
1c79356b
A
351 limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack;
352 limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data;
353 limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core;
354 limit0.p_refcnt = 1;
355
356 p->p_stats = &pstats0;
357 p->p_sigacts = &sigacts0;
358
359 /*
360 * Charge root for one process.
361 */
362 (void)chgproccnt(0, 1);
363
1c79356b
A
364 /*
365 * Allocate a kernel submap for pageable memory
765c9de3 366 * for temporary copying (execve()).
1c79356b
A
367 */
368 {
369 vm_offset_t min;
370
371 ret = kmem_suballoc(kernel_map,
372 &min,
765c9de3 373 (vm_size_t)BSD_PAGABLE_MAP_SIZE,
1c79356b
A
374 TRUE,
375 TRUE,
376 &bsd_pageable_map);
9bccf70c
A
377 if (ret != KERN_SUCCESS)
378 panic("bsd_init: Failed to allocate bsd pageable map");
765c9de3
A
379 }
380
381 /* Initialize the execve() semaphore */
9bccf70c
A
382 ret = semaphore_create(kernel_task, &execve_semaphore,
383 SYNC_POLICY_FIFO, (BSD_PAGABLE_MAP_SIZE / NCARGS));
384 if (ret != KERN_SUCCESS)
385 panic("bsd_init: Failed to create execve semaphore");
1c79356b
A
386
387 /*
0b4e3aa0
A
388 * Initialize the calendar.
389 */
1c79356b
A
390 IOKitResetTime();
391
392 ubc_init();
393
394 /* Initialize the file systems. */
395 vfsinit();
396
397 /* Initialize mbuf's. */
398 mbinit();
399
400 /* Initialize syslog */
401 log_init();
402
55e303ae
A
403 /*
404 * Initializes security event auditing.
405 * XXX: Should/could this occur later?
406 */
407 audit_init();
408
409 /* Initialize kqueues */
410 knote_init();
411
412 /* Initialize for async IO */
413 aio_init();
414
9bccf70c
A
415 /* POSIX Shm and Sem */
416 pshm_cache_init();
417 psem_cache_init();
418 time_zone_slock_init();
1c79356b 419
1c79356b
A
420 /*
421 * Initialize protocols. Block reception of incoming packets
422 * until everything is ready.
423 */
424 s = splimp();
425 sysctl_register_fixed();
43866e37 426 sysctl_mib_init();
1c79356b
A
427 dlil_init();
428 socketinit();
429 domaininit();
430 splx(s);
431
1c79356b
A
432 p->p_fd->fd_cdir = NULL;
433 p->p_fd->fd_rdir = NULL;
434
1c79356b
A
435#ifdef GPROF
436 /* Initialize kernel profiling. */
437 kmstartup();
438#endif
439
440 /* kick off timeout driven events by calling first time */
441 thread_wakeup(&lbolt);
55e303ae 442 timeout((void (*)(void *))lightning_bolt, 0, hz);
1c79356b
A
443
444 bsd_autoconf();
445
446 /*
447 * We attach the loopback interface *way* down here to ensure
448 * it happens after autoconf(), otherwise it becomes the
449 * "primary" interface.
450 */
451#include <loop.h>
452#if NLOOP > 0
453 loopattach(); /* XXX */
454#endif
9bccf70c
A
455
456 /* Register the built-in dlil ethernet interface family */
457 ether_family_init();
1c79356b
A
458
459 vnode_pager_bootstrap();
460
461 /* Mount the root file system. */
462 while( TRUE) {
463 int err;
464
465 setconf();
466 /*
467 * read the time after clock_initialize_calendar()
468 * and before nfs mount
469 */
55e303ae 470 microtime((struct timeval *)&time);
1c79356b 471
9bccf70c
A
472 bsd_hardclockinit = -1; /* start ticking */
473
1c79356b
A
474 if (0 == (err = vfs_mountroot()))
475 break;
9bccf70c
A
476 if (mountroot == netboot_mountroot) {
477 printf("cannot mount network root, errno = %d\n", err);
478 mountroot = NULL;
479 if (0 == (err = vfs_mountroot()))
480 break;
481 }
1c79356b
A
482 printf("cannot mount root, errno = %d\n", err);
483 boothowto |= RB_ASKNAME;
484 }
485
486 mountlist.cqh_first->mnt_flag |= MNT_ROOTFS;
487
488 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
489 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
765c9de3 490 panic("bsd_init: cannot find root vnode");
1c79356b 491 VREF(rootvnode);
fa4905b1 492 filedesc0.fd_cdir = rootvnode;
1c79356b 493 VOP_UNLOCK(rootvnode, 0, p);
9bccf70c
A
494
495 if (mountroot == netboot_mountroot) {
496 int err;
497 /* post mount setup */
498 if (err = netboot_setup(p)) {
499 panic("bsd_init: NetBoot could not find root, %d", err);
500 }
501 }
1c79356b
A
502
503
504 /*
505 * Now can look at time, having had a chance to verify the time
506 * from the file system. Reset p->p_rtime as it may have been
507 * munched in mi_switch() after the time got set.
508 */
509 p->p_stats->p_start = boottime = time;
510 p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
511
9bccf70c 512#if DEVFS
1c79356b
A
513 {
514 extern void devfs_kernel_mount(char * str);
515
516 devfs_kernel_mount("/dev");
517 }
55e303ae 518#endif /* DEVFS */
1c79356b
A
519
520 /* Initialize signal state for process 0. */
521 siginit(p);
522
1c79356b
A
523 bsd_utaskbootstrap();
524
9bccf70c
A
525 /* invoke post-root-mount hook */
526 if (mountroot_post_hook != NULL)
527 mountroot_post_hook();
528
529 (void) thread_funnel_set(kernel_flock, funnel_state);
1c79356b
A
530}
531
9bccf70c 532/* Called with kernel funnel held */
1c79356b 533void
9bccf70c 534bsdinit_task(void)
1c79356b
A
535{
536 struct proc *p = current_proc();
537 struct uthread *ut;
538 kern_return_t kr;
539 thread_act_t th_act;
55e303ae 540 shared_region_mapping_t system_region;
1c79356b 541
1c79356b
A
542 proc_name("init", p);
543
544 ux_handler_init();
1c79356b
A
545
546 th_act = current_act();
547 (void) host_set_exception_ports(host_priv_self(),
548 EXC_MASK_ALL & ~(EXC_MASK_SYSCALL |
549 EXC_MASK_MACH_SYSCALL |
550 EXC_MASK_RPC_ALERT),
551 ux_exception_port,
552 EXCEPTION_DEFAULT, 0);
553
554 (void) task_set_exception_ports(get_threadtask(th_act),
555 EXC_MASK_ALL & ~(EXC_MASK_SYSCALL |
556 EXC_MASK_MACH_SYSCALL |
557 EXC_MASK_RPC_ALERT),
558 ux_exception_port,
559 EXCEPTION_DEFAULT, 0);
560
561
562
563
564 ut = (uthread_t)get_bsdthread_info(th_act);
565 ut->uu_ar0 = (void *)get_user_regs(th_act);
566
567 bsd_hardclockinit = 1; /* Start bsd hardclock */
568 bsd_init_task = get_threadtask(th_act);
569 init_task_failure_data[0] = 0;
55e303ae
A
570 system_region = lookup_default_shared_region(ENV_DEFAULT_ROOT,
571 machine_slot[cpu_number()].cpu_type);
572 if (system_region == NULL) {
573 shared_file_boot_time_init(ENV_DEFAULT_ROOT,
574 machine_slot[cpu_number()].cpu_type);
575 } else {
576 vm_set_shared_region(get_threadtask(th_act), system_region);
577 }
1c79356b 578 load_init_program(p);
9bccf70c
A
579 /* turn on app-profiling i.e. pre-heating */
580 app_profile = 1;
1c79356b
A
581}
582
583void
584lightning_bolt()
585{
586 boolean_t funnel_state;
587 extern void klogwakeup(void);
588
589 funnel_state = thread_funnel_set(kernel_flock, TRUE);
590
591 thread_wakeup(&lbolt);
592 timeout(lightning_bolt,0,hz);
593 klogwakeup();
594
595 (void) thread_funnel_set(kernel_flock, FALSE);
596}
597
9bccf70c
A
598bsd_autoconf()
599{
600 extern kern_return_t IOKitBSDInit( void );
1c79356b
A
601
602 kminit();
603
604 /*
605 * Early startup for bsd pseudodevices.
606 */
607 {
608 struct pseudo_init *pi;
609
610 for (pi = pseudo_inits; pi->ps_func; pi++)
611 (*pi->ps_func) (pi->ps_count);
612 }
613
9bccf70c 614 return( IOKitBSDInit());
1c79356b
A
615}
616
617
55e303ae 618#include <sys/disklabel.h> /* for MAXPARTITIONS */
1c79356b
A
619
620setconf()
621{
622 extern kern_return_t IOFindBSDRoot( char * rootName,
623 dev_t * root, u_int32_t * flags );
1c79356b
A
624 u_int32_t flags;
625 kern_return_t err;
626
627 /*
628 * calls into IOKit can generate networking registrations
629 * which needs to be under network funnel. Right thing to do
630 * here is to drop the funnel alltogether and regrab it afterwards
631 */
632 thread_funnel_set(kernel_flock, FALSE);
633 err = IOFindBSDRoot( rootdevice, &rootdev, &flags );
634 thread_funnel_set(kernel_flock, TRUE);
635 if( err) {
636 printf("setconf: IOFindBSDRoot returned an error (%d);"
637 "setting rootdevice to 'sd0a'.\n", err); /* XXX DEBUG TEMP */
638 rootdev = makedev( 6, 0 );
639 strcpy( rootdevice, "sd0a" );
640 flags = 0;
641 }
642
1c79356b 643 if( flags & 1 ) {
9bccf70c
A
644 /* network device */
645 mountroot = netboot_mountroot;
1c79356b
A
646 } else {
647 /* otherwise have vfs determine root filesystem */
648 mountroot = NULL;
649 }
650
651}
652
653bsd_utaskbootstrap()
654{
655 thread_act_t th_act;
9bccf70c 656 struct uthread *ut;
1c79356b 657
9bccf70c 658 th_act = cloneproc(kernproc, 0);
1c79356b 659 initproc = pfind(1);
9bccf70c
A
660 /* Set the launch time for init */
661 initproc->p_stats->p_start = time;
662
663 ut = (struct uthread *)get_bsdthread_info(th_act);
664 ut->uu_sigmask = 0;
9bccf70c 665 act_set_astbsd(th_act);
1c79356b
A
666 (void) thread_resume(th_act);
667}
668
669parse_bsd_args()
670{
671 extern char init_args[];
672 char namep[16];
673 extern int boothowto;
674 extern int srv;
675 extern int ncl;
676
677 int len;
678
679 if (PE_parse_boot_arg("-s", namep)) {
680 boothowto |= RB_SINGLE;
681 len = strlen(init_args);
682 if(len != 0)
683 strcat(init_args," -s");
684 else
685 strcat(init_args,"-s");
686 }
55e303ae 687
1c79356b
A
688 if (PE_parse_boot_arg("-b", namep)) {
689 boothowto |= RB_NOBOOTRC;
690 len = strlen(init_args);
691 if(len != 0)
692 strcat(init_args," -b");
693 else
694 strcat(init_args,"-b");
695 }
696
697 if (PE_parse_boot_arg("-F", namep)) {
698 len = strlen(init_args);
699 if(len != 0)
700 strcat(init_args," -F");
701 else
702 strcat(init_args,"-F");
703 }
704
705 if (PE_parse_boot_arg("-v", namep)) {
706 len = strlen(init_args);
707 if(len != 0)
708 strcat(init_args," -v");
709 else
710 strcat(init_args,"-v");
711 }
712
713 if (PE_parse_boot_arg("-x", namep)) { /* safe boot */
714 len = strlen(init_args);
715 if(len != 0)
716 strcat(init_args," -x");
717 else
718 strcat(init_args,"-x");
719 }
720
55e303ae
A
721 if (PE_parse_boot_arg("-d", namep)) {
722 len = strlen(init_args);
723 if(len != 0)
724 strcat(init_args," -d");
725 else
726 strcat(init_args,"-d");
727 }
728
1c79356b
A
729 PE_parse_boot_arg("srv", &srv);
730 PE_parse_boot_arg("ncl", &ncl);
731 PE_parse_boot_arg("nbuf", &nbuf);
732
733 return 0;
734}
735
736boolean_t
737thread_funnel_switch(
738 int oldfnl,
739 int newfnl)
740{
1c79356b
A
741 boolean_t funnel_state_prev;
742 int curfnl;
743 funnel_t * curflock;
744 funnel_t * oldflock;
745 funnel_t * newflock;
746 funnel_t * exist_funnel;
747 extern int disable_funnel;
748
749
750 if (disable_funnel)
751 return(TRUE);
752
753 if(oldfnl == newfnl) {
754 panic("thread_funnel_switch: can't switch to same funnel");
755 }
756
9bccf70c 757 if ((oldfnl != NETWORK_FUNNEL) && (oldfnl != KERNEL_FUNNEL)) {
1c79356b
A
758 panic("thread_funnel_switch: invalid oldfunnel");
759 }
9bccf70c
A
760 if ((newfnl != NETWORK_FUNNEL) && (newfnl != KERNEL_FUNNEL)) {
761 panic("thread_funnel_switch: invalid newfunnel");
1c79356b
A
762 }
763
764 if((curflock = thread_funnel_get()) == THR_FUNNEL_NULL) {
765 panic("thread_funnel_switch: no funnel held");
766 }
767
1c79356b
A
768 if ((oldfnl == NETWORK_FUNNEL) && (curflock != network_flock))
769 panic("thread_funnel_switch: network funnel not held");
770
771 if ((oldfnl == KERNEL_FUNNEL) && (curflock != kernel_flock))
9bccf70c 772 panic("thread_funnel_switch: kernel funnel not held");
1c79356b
A
773
774 if(oldfnl == NETWORK_FUNNEL) {
775 oldflock = network_flock;
776 newflock = kernel_flock;
777 } else {
778 oldflock = kernel_flock;
779 newflock = network_flock;
780 }
781 KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE, oldflock, 1, 0, 0, 0);
782 thread_funnel_set(oldflock, FALSE);
783 KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE, newflock, 1, 0, 0, 0);
784 thread_funnel_set(newflock, TRUE);
785 KERNEL_DEBUG(0x6032434 | DBG_FUNC_NONE, newflock, 1, 0, 0, 0);
786
787 return(TRUE);
788}