Annotation of kernel/bsd/kern/init_main.c, revision 1.1.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.