|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 ! 27: * The Regents of the University of California. All rights reserved. ! 28: * (c) UNIX System Laboratories, Inc. ! 29: * All or some portions of this file are derived from material licensed ! 30: * to the University of California by American Telephone and Telegraph ! 31: * Co. or Unix System Laboratories, Inc. and are reproduced herein with ! 32: * the permission of UNIX System Laboratories, Inc. ! 33: * ! 34: * Redistribution and use in source and binary forms, with or without ! 35: * modification, are permitted provided that the following conditions ! 36: * are met: ! 37: * 1. Redistributions of source code must retain the above copyright ! 38: * notice, this list of conditions and the following disclaimer. ! 39: * 2. Redistributions in binary form must reproduce the above copyright ! 40: * notice, this list of conditions and the following disclaimer in the ! 41: * documentation and/or other materials provided with the distribution. ! 42: * 3. All advertising materials mentioning features or use of this software ! 43: * must display the following acknowledgement: ! 44: * This product includes software developed by the University of ! 45: * California, Berkeley and its contributors. ! 46: * 4. Neither the name of the University nor the names of its contributors ! 47: * may be used to endorse or promote products derived from this software ! 48: * without specific prior written permission. ! 49: * ! 50: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 51: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 52: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 53: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 54: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 55: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 56: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 57: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 58: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 59: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 60: * SUCH DAMAGE. ! 61: * ! 62: * @(#)init_main.c 8.16 (Berkeley) 5/14/95 ! 63: */ ! 64: ! 65: /* ! 66: * ! 67: * Mach Operating System ! 68: * Copyright (c) 1987 Carnegie-Mellon University ! 69: * All rights reserved. The CMU software License Agreement specifies ! 70: * the terms and conditions for use and redistribution. ! 71: */ ! 72: /* ! 73: * HISTORY ! 74: * 02-Jul-97 Umesh Vaishampayan at Apple ! 75: * Cleanup. ! 76: * ! 77: * 06-Jan-93 Mac Gillon at NeXT ! 78: * POSIX support ! 79: * ! 80: * 20-Apr-90 Doug Mitchell at NeXT ! 81: * Started up reaper_thread() before mounting root. ! 82: * ! 83: * 19-Mar-90 Gregg Kellogg (gk) at NeXT ! 84: * NeXT doesn't use schedcpu. ! 85: * Move kallocinit() to vm/vm_init.c ! 86: * ! 87: * 14-Feb-90 Gregg Kellogg (gk) at NeXT ! 88: * Changes for new scheduler: ! 89: * Initialize scheduler ! 90: * use newproc() to start ux_handler. ! 91: * Remove process lock initialization. ! 92: * Remove obsolete service_timers() kickoff ! 93: * do callout_lock initialization in kern_synch.c/rqinit. ! 94: * ! 95: * 17-Jan-90 Morris Meyer (mmeyer) at NeXT ! 96: * NFS 4.0 Changes: Minimal cleanup. Removed ihinit. ! 97: * ! 98: * 07-Nov-88 Avadis Tevanian (avie) at NeXT ! 99: * Removed code to use transparent addresses since it only works ! 100: * when we have fully populated buffers (which is a bad assumption). ! 101: * ! 102: * 13-Aug-88 Avadis Tevanian (avie) at NeXT ! 103: * Removed dependencies on proc table. ! 104: * ! 105: * 4-May-88 David Black (dlb) at Carnegie-Mellon University ! 106: * MACH_TIME_NEW is now standard. ! 107: * ! 108: * 21-Apr-88 David Black (dlb) at Carnegie-Mellon University ! 109: * Set kernel_only for kernel task. ! 110: * ! 111: * 10-Apr-88 John Seamons (jks) at NeXT ! 112: * NeXT: Improve TLB performance for buffers by using the ! 113: * transparently translated virtual address for single page sized bufs. ! 114: * ! 115: * 07-Apr-88 John Seamons (jks) at NeXT ! 116: * NeXT: reduced the allocation size of various zones to save space. ! 117: * ! 118: * 3-Apr-88 Michael Young (mwyoung) at Carnegie-Mellon University ! 119: * Force the vm_map for the inode_ and device_ pager tasks to ! 120: * be the kernel map. ! 121: * ! 122: * 25-Jan-88 Richard Sanzi (sanzi) at Carnegie-Mellon University ! 123: * Moved float_init() call to configure() in autoconf.c ! 124: * ! 125: * 21-Jan-88 David Golub (dbg) at Carnegie-Mellon University ! 126: * Neither task_create nor thread_create return the data port ! 127: * any longer. ! 128: * ! 129: * 29-Dec-87 David Golub (dbg) at Carnegie-Mellon University ! 130: * Removed code to shuffle initial processes for idle threads; ! 131: * MACH doesn't need to make extra processes for them. ! 132: * Delinted. ! 133: * ! 134: * 12-Dec-87 Michael Young (mwyoung) at Carnegie-Mellon University ! 135: * Added device_pager startup. Moved setting of ipc_kernel and ! 136: * kernel_only flags here. ! 137: * ! 138: * 9-Dec-87 David Golub (dbg) at Carnegie-Mellon University ! 139: * Follow thread_terminate with thread_halt_self for new thread ! 140: * termination logic; extra reference no longer necessary. ! 141: * ! 142: * 9-Dec-87 David Black (dlb) at Carnegie-Mellon University ! 143: * Grab extra reference to first thread before terminating it. ! 144: * ! 145: * 4-Dec-87 David Black (dlb) at Carnegie-Mellon University ! 146: * Name changes for exc interface. set ipc_kernel in first thread ! 147: * for paranoia purposes. ! 148: * ! 149: * 19-Nov-87 Avadis Tevanian (avie) at Carnegie-Mellon University ! 150: * Eliminated MACH conditionals, purged history. ! 151: * ! 152: * 5-Nov-87 David Golub (dbg) at Carnegie-Mellon University ! 153: * start up network service thread. ! 154: * ! 155: * 9-Sep-87 Peter King (king) at NeXT ! 156: * SUN_VFS: Add a call to vfs_init() in setup_main(). ! 157: * ! 158: * 17-Aug-87 Peter King (king) at NeXT ! 159: * SUN_VFS: Support credentials record in u. ! 160: * Convert to Sun quota system. ! 161: * Add call to dnlc_init(). Remove nchinit() call. ! 162: * Call swapconf() in binit(). ! 163: */ ! 164: ! 165: #import <mach_xp.h> ! 166: #import <quota.h> ! 167: #import <cpus.h> ! 168: #import <cputypes.h> ! 169: #import <mach_old_vm_copy.h> ! 170: ! 171: ! 172: #import <sys/param.h> ! 173: #import <sys/filedesc.h> ! 174: #import <sys/kernel.h> ! 175: #import <sys/mount.h> ! 176: #import <sys/proc.h> ! 177: #import <sys/systm.h> ! 178: #import <sys/vnode.h> ! 179: #import <sys/conf.h> ! 180: #import <sys/buf.h> ! 181: #import <sys/clist.h> ! 182: #import <sys/user.h> ! 183: ! 184: #import <ufs/ufs/quota.h> ! 185: ! 186: #import <machine/cpu.h> ! 187: ! 188: #import <sys/malloc.h> ! 189: #import <sys/dkstat.h> ! 190: #import <machine/reg.h> ! 191: #import <machine/spl.h> ! 192: ! 193: #import <kern/thread.h> ! 194: #import <kern/task.h> ! 195: #import <mach/machine.h> ! 196: #import <kern/timer.h> ! 197: #import <sys/version.h> ! 198: #import <machdep/machine/pmap.h> ! 199: #import <mach/vm_param.h> ! 200: #import <vm/vm_page.h> ! 201: #import <vm/vm_map.h> ! 202: #import <vm/vm_kern.h> ! 203: #import <vm/vm_object.h> ! 204: #import <mach/boolean.h> ! 205: #import <kern/sched_prim.h> ! 206: #import <kern/zalloc.h> ! 207: #if MACH_XP ! 208: #import <vm/vnode_pager.h> ! 209: #import <vm/device_pager.h> ! 210: #endif /* MACH_XP */ ! 211: ! 212: #import <mach/task_special_ports.h> ! 213: #import <sys/ux_exception.h> ! 214: #import <sys/reboot.h> ! 215: #import "kernobjc.h" ! 216: #import "driverkit.h" ! 217: ! 218: #if NeXT ! 219: #import <kern/power.h> ! 220: #import <kern/parallel.h> ! 221: #endif /* NeXT */ ! 222: ! 223: char copyright[] = ! 224: "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; ! 225: ! 226: extern void ux_handler(); ! 227: ! 228: /* Components of the first process -- never freed. */ ! 229: struct proc proc0; ! 230: struct session session0; ! 231: struct pgrp pgrp0; ! 232: struct pcred cred0; ! 233: struct filedesc filedesc0; ! 234: struct plimit limit0; ! 235: struct pstats pstats0; ! 236: struct sigacts sigacts0; ! 237: struct proc *kernproc, *initproc; ! 238: ! 239: ! 240: long cp_time[CPUSTATES]; ! 241: long dk_seek[DK_NDRIVE]; ! 242: long dk_time[DK_NDRIVE]; ! 243: long dk_wds[DK_NDRIVE]; ! 244: long dk_wpms[DK_NDRIVE]; ! 245: long dk_xfer[DK_NDRIVE]; ! 246: long dk_bps[DK_NDRIVE]; ! 247: ! 248: int dk_busy; ! 249: int dk_ndrive; ! 250: ! 251: long tk_cancc; ! 252: long tk_nin; ! 253: long tk_nout; ! 254: long tk_rawcc; ! 255: ! 256: #if NeXT ! 257: thread_t pageoutThread; ! 258: /* Global variables to make pstat happy. We do swapping differently */ ! 259: int nswdev, nswap; ! 260: int nswapmap; ! 261: void *swapmap; ! 262: struct swdevt swdevt[1]; ! 263: #endif /* NeXT */ ! 264: ! 265: dev_t rootdev; /* device of the root */ ! 266: dev_t dumpdev; /* device to take dumps on */ ! 267: long dumplo; /* offset into dumpdev */ ! 268: extern int show_space; ! 269: long hostid; ! 270: char hostname[MAXHOSTNAMELEN]; ! 271: int hostnamelen; ! 272: char domainname[MAXDOMNAMELEN]; ! 273: int domainnamelen; ! 274: ! 275: struct timeval boottime; /* GRODY! This has to go... */ ! 276: struct timeval time; ! 277: ! 278: #ifdef KMEMSTATS ! 279: struct kmemstats kmemstats[M_LAST]; ! 280: #endif ! 281: ! 282: int lbolt; /* awoken once a second */ ! 283: struct vnode *rootvp; ! 284: ! 285: vm_map_t kernel_pageable_map; ! 286: vm_map_t mb_map; ! 287: ! 288: int cmask = CMASK; ! 289: /* ! 290: * Initialization code. ! 291: * Called from cold start routine as ! 292: * soon as a stack and segmentation ! 293: * have been established. ! 294: * Functions: ! 295: * clear and free user core ! 296: * turn on clock ! 297: * hand craft 0th process ! 298: * call all initialization routines ! 299: * fork - process 0 to schedule ! 300: * - process 1 execute bootstrap ! 301: * - process 2 to page out ! 302: */ ! 303: ! 304: /* ! 305: * Sets the name for the given task. ! 306: */ ! 307: void task_name(s, p) ! 308: char *s; ! 309: struct proc *p; ! 310: { ! 311: int length = strlen(s); ! 312: ! 313: bcopy(s, p->p_comm, ! 314: length >= sizeof(p->p_comm) ? sizeof(p->p_comm) : ! 315: length + 1); ! 316: } ! 317: ! 318: #if KERNOBJC ! 319: static int kernDefaultClassHandler(const char *className) ! 320: { ! 321: return 0; ! 322: } ! 323: #endif /* KERNOBJC */ ! 324: ! 325: /* To allow these values to be patched, they're globals here */ ! 326: #import <machine/vmparam.h> ! 327: struct rlimit vm_initial_limit_stack = { DFLSSIZ, MAXSSIZ }; ! 328: struct rlimit vm_initial_limit_data = { DFLDSIZ, MAXDSIZ }; ! 329: struct rlimit vm_initial_limit_core = { DFLCSIZ, MAXCSIZ }; ! 330: ! 331: extern thread_t first_thread; ! 332: ! 333: #define SPL_DEBUG 0 ! 334: #if SPL_DEBUG ! 335: #define dprintf(x) printf x ! 336: #else SPL_DEBUG ! 337: #define dprintf(x) ! 338: #endif /* SPL_DEBUG */ ! 339: ! 340: void ! 341: main() ! 342: { ! 343: register struct proc *p; ! 344: extern struct ucred *rootcred; ! 345: register int i; ! 346: int s; ! 347: thread_t th; ! 348: extern void idle_thread(), init_task(), vm_pageout(); ! 349: extern void reaper_thread(), swapin_thread(); ! 350: extern void netisr_thread(), sched_thread(); ! 351: #if NeXT ! 352: extern int power_callout(void *, void *); ! 353: #endif /* NeXT */ ! 354: ! 355: #if PRELOAD ! 356: extern void prepagein_thread(); ! 357: #endif ! 358: #if NCPUS > 1 ! 359: extern void action_thread(); ! 360: #endif /* NCPUS > 1 */ ! 361: #if MACH_XP ! 362: thread_t inode_th; ! 363: thread_t device_th; ! 364: #endif /* MACH_XP */ ! 365: void lightning_bolt(void *, void *); ! 366: extern thread_t cloneproc(); ! 367: ! 368: extern int (*mountroot) __P((void)); ! 369: ! 370: dprintf(("main entry: curspl=0x%x\n", curspl())); ! 371: ! 372: printf(copyright); ! 373: ! 374: kmeminit(); ! 375: ! 376: /* ! 377: * Initialize process and pgrp structures. ! 378: */ ! 379: procinit(); ! 380: ! 381: kernproc = &proc0; ! 382: ! 383: p = kernproc; ! 384: kernel_task->proc = kernproc; ! 385: p->p_pid = 0; ! 386: ! 387: /* ! 388: * Create process 0. ! 389: */ ! 390: LIST_INSERT_HEAD(&allproc, p, p_list); ! 391: p->p_pgrp = &pgrp0; ! 392: LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); ! 393: LIST_INIT(&pgrp0.pg_members); ! 394: LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); ! 395: ! 396: pgrp0.pg_session = &session0; ! 397: session0.s_count = 1; ! 398: session0.s_leader = p; ! 399: ! 400: p->task = kernel_task; ! 401: /* ! 402: * Now in thread context, switch to thread timer. ! 403: */ ! 404: s = splhigh(); ! 405: dprintf(("main splhigh: curspl=0x%x\n", curspl())); ! 406: timer_switch(¤t_thread()->system_timer); ! 407: splx(s); ! 408: dprintf(("main splx: curspl=0x%x\n", curspl())); ! 409: ! 410: thread_call_init(); ! 411: ! 412: p->p_stat = SRUN; ! 413: p->p_flag = P_INMEM|P_SYSTEM; ! 414: p->p_nice = NZERO; ! 415: p->p_pptr = p; ! 416: simple_lock_init(&p->siglock); ! 417: p->sigwait = FALSE; ! 418: p->sigwait_thread = THREAD_NULL; ! 419: p->exit_thread = THREAD_NULL; ! 420: ! 421: /* Create credentials. */ ! 422: lockinit(&cred0.pc_lock, PLOCK, "proc0 cred", 0, 0); ! 423: cred0.p_refcnt = 1; ! 424: p->p_cred = &cred0; ! 425: p->p_ucred = crget(); ! 426: p->p_ucred->cr_ngroups = 1; /* group 0 */ ! 427: ! 428: /* Create the file descriptor table. */ ! 429: filedesc0.fd_refcnt = 1; ! 430: p->p_fd = &filedesc0; ! 431: filedesc0.fd_cmask = cmask; ! 432: ! 433: /* Create the limits structures. */ ! 434: p->p_limit = &limit0; ! 435: for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) ! 436: limit0.pl_rlimit[i].rlim_cur = ! 437: limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; ! 438: limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; ! 439: limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; ! 440: limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack; ! 441: limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data; ! 442: limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core; ! 443: limit0.p_refcnt = 1; ! 444: ! 445: p->p_stats = &pstats0; ! 446: p->p_sigacts = &sigacts0; ! 447: ! 448: /* ! 449: * Charge root for one process. ! 450: */ ! 451: (void)chgproccnt(0, 1); ! 452: ! 453: /* ! 454: * Allocate a kernel submap for pageable memory ! 455: * for temporary copying (table(), execve()). ! 456: */ ! 457: { ! 458: vm_offset_t min, max; ! 459: ! 460: kernel_pageable_map = kmem_suballoc(kernel_map, ! 461: &min, &max, ! 462: 512*1024, ! 463: TRUE); ! 464: #if MACH_OLD_VM_COPY ! 465: #else MACH_OLD_VM_COPY ! 466: kernel_pageable_map->wait_for_space = TRUE; ! 467: #endif /* MACH_OLD_VM_COPY */ ! 468: } ! 469: ! 470: hardclock_init(); ! 471: ! 472: mapfs_init(); ! 473: ! 474: /* Initialize the file systems. */ ! 475: vfsinit(); ! 476: ! 477: /* Initialize mbuf's. */ ! 478: mbinit(); ! 479: ! 480: /* Initialize syslog */ ! 481: log_init(); ! 482: ! 483: /* ! 484: * Initialize protocols. Block reception of incoming packets ! 485: * until everything is ready. ! 486: */ ! 487: s = splimp(); ! 488: ifinit(); ! 489: socketinit(); ! 490: domaininit(); ! 491: splx(s); ! 492: ! 493: /* ! 494: * Create kernel idle cpu processes. This must be done ! 495: * before a context switch can occur (and hence I/O can ! 496: * happen in the binit() call). ! 497: */ ! 498: p->p_fd->fd_cdir = NULL; ! 499: p->p_fd->fd_rdir = NULL; ! 500: ! 501: for (i = 0; i < NCPUS; i++) { ! 502: if (machine_slot[i].is_cpu == FALSE) ! 503: continue; ! 504: (void) thread_create(kernel_task, &th); ! 505: thread_bind(th, cpu_to_processor(i)); ! 506: thread_start(th, idle_thread); ! 507: thread_doswapin(th); ! 508: (void) thread_resume(th); ! 509: } ! 510: ! 511: #ifdef GPROF ! 512: /* Initialize kernel profiling. */ ! 513: kmstartup(); ! 514: #endif ! 515: ! 516: /* kick off timeout driven events by calling first time */ ! 517: lightning_bolt(0, 0); ! 518: ! 519: /* ! 520: * Start up netisr thread now in case we are doing an nfs_mountroot. ! 521: */ ! 522: (void) kernel_thread(kernel_task, reaper_thread, (void *)0); ! 523: (void) kernel_thread(kernel_task, swapin_thread, (void *)0); ! 524: (void) kernel_thread(kernel_task, sched_thread, (void *)0); ! 525: #if NCPUS > 1 ! 526: (void) kernel_thread(kernel_task, action_thread, (void *)0); ! 527: #endif /* NCPUS > 1 */ ! 528: (void) kernel_thread(kernel_task, netisr_thread, (void *)0); ! 529: ! 530: #if KERNOBJC ! 531: _objcInit(); ! 532: objc_setClassHandler(kernDefaultClassHandler); ! 533: #endif /* KERNOBJC */ ! 534: ! 535: #ifdef DRIVERKIT ! 536: /* Spin cursor in a fashion vaguely similar to 68k boot ROM. ! 537: * Eventually this will be the same on all architectures. ! 538: */ ! 539: kmEnableAnimation(); ! 540: #if defined(ppc) ! 541: /* this is temporary - until driver kit works */ ! 542: #warning this is temporary too ! 543: bsd_autoconf(); ! 544: #endif ! 545: ! 546: autoconf(); ! 547: ! 548: #elif /* DRIVERKIT */ ! 549: #warning this is temporary ! 550: /* this is temporary - until driver kit works */ ! 551: bsd_autoconf(); ! 552: #endif /* DRIVERKIT */ ! 553: ! 554: /* ! 555: * We attach the loopback interface *way* down here to ensure ! 556: * it happens after autoconf(), otherwise it becomes the ! 557: * "primary" interface. ! 558: */ ! 559: #import <loop.h> ! 560: #if NLOOP > 0 ! 561: loopattach(); /* XXX */ ! 562: #endif ! 563: ! 564: /* Mount the root file system. */ ! 565: while( TRUE) { ! 566: int err; ! 567: ! 568: setconf(); ! 569: if (0 == (err = vfs_mountroot())) ! 570: break; ! 571: printf("cannot mount root, errno = %d\n", err); ! 572: boothowto |= RB_ASKNAME; ! 573: } ! 574: ! 575: mountlist.cqh_first->mnt_flag |= MNT_ROOTFS; ! 576: ! 577: /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ ! 578: if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) ! 579: panic("cannot find root vnode"); ! 580: filedesc0.fd_cdir = rootvnode; ! 581: VREF(rootvnode); ! 582: VOP_UNLOCK(rootvnode, 0, p); ! 583: ! 584: /* ! 585: * Now can look at time, having had a chance to verify the time ! 586: * from the file system. Reset p->p_rtime as it may have been ! 587: * munched in mi_switch() after the time got set. ! 588: */ ! 589: p->p_stats->p_start = boottime = time; ! 590: p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; ! 591: ! 592: /* Initialize signal state for process 0. */ ! 593: siginit(p); ! 594: ! 595: /* ! 596: * make init process ! 597: */ ! 598: ! 599: th = cloneproc(kernproc); ! 600: th->task->kernel_privilege = FALSE; /* XXX cleaner way to do this? ! 601: */ ! 602: #if NeXT ! 603: initproc = pfind(1); /* now that it is set */ ! 604: #endif /* NeXT */ ! 605: /* ! 606: * After calling start_init, ! 607: * machine-dependent code must ! 608: * set up stack as though a system ! 609: * call trap occurred, then call ! 610: * load_init_program. ! 611: */ ! 612: ! 613: /* ! 614: * Start up unix exception server ! 615: */ ! 616: ux_handler_init(); ! 617: port_reference(ux_exception_port); ! 618: (void) task_set_exception_port(th->task, ux_exception_port); ! 619: ! 620: thread_start(th, init_task); ! 621: (void) thread_resume(th); ! 622: ! 623: /* ! 624: * Kernel daemon threads that don't need their own tasks ! 625: */ ! 626: ! 627: /* ! 628: * Initialize power management ! 629: */ ! 630: power_init(); ! 631: ! 632: pageoutThread = kernel_thread(kernel_task, vm_pageout, (void *)0); ! 633: ! 634: /* ! 635: * vol driver and notification server startup ! 636: */ ! 637: #if NeXT ! 638: vol_start_thread(); ! 639: pnotify_start(); ! 640: #endif /* NeXT */ ! 641: ! 642: #if NeXT && NCPUS > 1 ! 643: /* ! 644: * The CMU VAX code does this from the start_init() code, ! 645: * but that seems like an "unusual" place to do it. (Like ! 646: * I didn't look there right away :-). Doing this here isn't ! 647: * much better, but it is one of the places I looked. This ! 648: * can't be done until the idle threads are created for each ! 649: * cpu (see about 50 lines above). ! 650: */ ! 651: start_other_cpus(); ! 652: #endif /* NeXT && NCPUS > 1 */ ! 653: ! 654: task_name("kernel idle", p); ! 655: (void) thread_terminate(current_thread()); ! 656: thread_halt_self(); ! 657: /*NOTREACHED*/ ! 658: } ! 659: ! 660: void ! 661: init_task() ! 662: { ! 663: struct proc *p = current_proc(); ! 664: ! 665: task_name("init", p); ! 666: ! 667: current_thread()->_uthread->uu_ar0 = (void *)USER_REGS(current_thread()); ! 668: ! 669: load_init_program(p); ! 670: ! 671: thread_exception_return(); ! 672: /*NOTREACHED*/ ! 673: } ! 674: ! 675: void ! 676: lightning_bolt( ! 677: thread_call_spec_t argument, ! 678: thread_call_t callout ! 679: ) ! 680: { ! 681: thread_wakeup(&lbolt); ! 682: ! 683: if (!callout) ! 684: callout = thread_call_allocate(lightning_bolt, 0); ! 685: ! 686: thread_call_enter_delayed(callout, ! 687: deadline_from_interval((tvalspec_t) { 1, 0 } )); ! 688: } ! 689:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.