Annotation of kernel/bsd/kern/init_main.c, revision 1.1

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(&current_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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.