Annotation of kernel/machdep/i386/unix_startup.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) 1992 NeXT Computer, Inc.
        !            27:  *
        !            28:  * Unix data structure initialization.
        !            29:  *
        !            30:  * HISTORY
        !            31:  *
        !            32:  * 26 May 1992 ? at NeXT
        !            33:  *     Created from 68k version.
        !            34:  */
        !            35: 
        !            36: #import <mach/mach_types.h>
        !            37: 
        !            38: #import <vm/vm_kern.h>
        !            39: #import <vm/vm_page.h>
        !            40: 
        !            41: #import <kernserv/ns_timer.h>
        !            42: 
        !            43: #import <sys/param.h>
        !            44: #import <sys/buf.h>
        !            45: #import <sys/callout.h>
        !            46: #import <sys/clist.h>
        !            47: #import <sys/mbuf.h>
        !            48: #import <sys/systm.h>
        !            49: #import <sys/tty.h>
        !            50: 
        !            51: extern struct tty      cons;
        !            52: 
        !            53: #import <kern/assert.h>
        !            54: 
        !            55: /*
        !            56:  * Declare these as initialized data so we can patch them.
        !            57:  */
        !            58: int    niobuf = 0;
        !            59: 
        !            60: #ifdef NBUF
        !            61: int            nbuf = NBUF;
        !            62: #else
        !            63: int            nbuf = 0;
        !            64: #endif
        !            65: #ifdef NMFSBUF
        !            66: int    nmfsbuf = NMFSBUF
        !            67: #else
        !            68: int    nmfsbuf = 0;
        !            69: #endif
        !            70: #ifdef BUFPAGES
        !            71: int            bufpages = BUFPAGES;
        !            72: #else
        !            73: int            bufpages = 0;
        !            74: #endif
        !            75: int            show_space = 0;
        !            76: int              srv;        /* Flag indicates a server boot when set */
        !            77: int             ncl = 0;
        !            78: vm_map_t       buffer_map;
        !            79: 
        !            80: /*
        !            81:  * Machine-dependent startup code
        !            82:  */
        !            83: /*
        !            84:  * Machine-dependent early startup code
        !            85:  */
        !            86: #if     SHOW_SPACE
        !            87: 
        !            88: #define valloc(name, type, num)                                                \
        !            89: MACRO_BEGIN                                                            \
        !            90:     (name) = (type *)(v); (v) = (vm_offset_t)((name)+(num));           \
        !            91:     if (show_space)                                                    \
        !            92:        printf(#name " = %d(0x%x) bytes @%x, %d cells @ %d bytes\n",    \
        !            93:            num*sizeof(type),                                           \
        !            94:            num*sizeof(type),                                           \
        !            95:            name, num, sizeof(type));                                   \
        !            96: MACRO_END
        !            97: 
        !            98: #define valloclim(name, type, num, lim)                                \
        !            99: MACRO_BEGIN                                                            \
        !           100:     (name) = (type *)(v); (v) = (vm_offset_t)((lim) = ((name)+(num))); \
        !           101:     if (show_space)                                                    \
        !           102:        printf(#name " = %d(0x%x) bytes @%x, %d cells @ %d bytes\n",    \
        !           103:            num*sizeof(type),                                           \
        !           104:            num*sizeof(type),                                           \
        !           105:            name, num, sizeof(type));                                   \
        !           106: MACRO_END
        !           107: 
        !           108: #else   SHOW_SPACE
        !           109: 
        !           110: #define valloc(name, type, num)                                        \
        !           111:     (name) = (type *)(v); (v) = (vm_offset_t)((name)+(num))
        !           112: 
        !           113: #define valloclim(name, type, num, lim)                                \
        !           114:     (name) = (type *)(v); (v) = (vm_offset_t)((lim) = ((name)+(num)));
        !           115: 
        !           116: #endif  SHOW_SPACE
        !           117: 
        !           118: vm_size_t
        !           119: buffer_map_sizer(void)
        !           120: {
        !           121: 
        !           122:     /*
        !           123:      *      Since these pages are virtual-size pages (larger
        !           124:      *      than physical page size), use only one page
        !           125:      *      per buffer.
        !           126:      */
        !           127:     if (bufpages == 0) {
        !           128:                bufpages = atop(mem_size / 50);
        !           129:     }
        !           130: 
        !           131:     if (nbuf == 0) {
        !           132: #if     PRIVATE_BUFS
        !           133:            nbuf = 100;
        !           134: #else   PRIVATE_BUFS
        !           135:        /* Go for a 1-1 correspondence between the number of buffer
        !           136:         * headers and bufpages.  Then add some extra (empty) buffer
        !           137:         * headers to aid clustering.
        !           138:         */
        !           139:        if ((nbuf = bufpages) < 16)
        !           140:                        nbuf = 16;
        !           141:        nbuf += 64;
        !           142: #endif  PRIVATE_BUFS
        !           143:     }
        !           144: 
        !           145:     if (bufpages > nbuf * (MAXBSIZE / page_size))
        !           146:        bufpages = nbuf * (MAXBSIZE / page_size);
        !           147: 
        !           148:     if (niobuf == 0) {
        !           149:                if ((niobuf = bufpages / (MAXPHYSIO / page_size)) > 1024)
        !           150:                        niobuf = 1024;
        !           151:                if (niobuf < 32)
        !           152:                        niobuf = 32;
        !           153:        }
        !           154: 
        !           155:     return (round_page(((vm_size_t)nbuf * MAXBSIZE)) + ((vm_size_t)niobuf
        !           156:                        * MAXPHYSIO));
        !           157:        }
        !           158: 
        !           159: void
        !           160: startup_early(void)
        !           161: {
        !           162:     vm_offset_t                firstaddr, v;
        !           163:     mem_region_t       rp  = mem_region;
        !           164: 
        !           165:     v = firstaddr = pmap_phys_to_kern(rp->first_phys_addr);
        !           166:     (void) buffer_map_sizer();
        !           167: 
        !           168:     valloc(buf, struct buf, nbuf + niobuf);
        !           169: 
        !           170:        /*
        !           171:         * Unless set at the boot command line, mfs gets no more than
        !           172:         * half of the system's bufs.  Hack to prevent buf starvation
        !           173:         * and system hang.
        !           174:         */
        !           175:        if (nmfsbuf == 0)
        !           176:                nmfsbuf = nbuf / 2;
        !           177: 
        !           178:     /*
        !           179:      * Clear space allocated thus far, and make r/w entries
        !           180:      * for the space in the kernel map.
        !           181:      */
        !           182: 
        !           183:     bzero(firstaddr, v - firstaddr);
        !           184:     rp->first_phys_addr = pmap_resident_extract(kernel_pmap, v);
        !           185: 
        !           186:     if (mem_size > (64 * 1024 * 1024)) {
        !           187:             int scale;
        !           188:            extern u_long tcp_sendspace;
        !           189:            extern u_long tcp_recvspace;
        !           190: 
        !           191:            if ((nmbclusters = ncl) == 0) {
        !           192:                    if ((nmbclusters = ((mem_size / 16) / MCLBYTES)) > 4096)
        !           193:                            nmbclusters = 8192;
        !           194:            }
        !           195:            if ((scale = nmbclusters / NMBCLUSTERS) > 1) {
        !           196:                    tcp_sendspace *= scale;
        !           197:                    tcp_recvspace *= scale;
        !           198: 
        !           199:                    if (tcp_sendspace > (32 * 1024))
        !           200:                            tcp_sendspace = 32 * 1024;
        !           201:                    if (tcp_recvspace > (32 * 1024))
        !           202:                            tcp_recvspace = 32 * 1024;
        !           203:            }
        !           204:     }
        !           205: }
        !           206: 
        !           207: 
        !           208: startup(
        !           209:     vm_offset_t                firstaddr
        !           210: )
        !           211: {
        !           212:     unsigned int       i;
        !           213:     vm_size_t          map_size;
        !           214:     kern_return_t      ret;
        !           215:     vm_offset_t                buffer_max;
        !           216:     int                        base, residual;
        !           217:     extern int         vm_page_free_count;
        !           218:     mem_region_t       rp = mem_region;
        !           219: 
        !           220:     cons.t_dev = makedev(12, 0);
        !           221: 
        !           222:     kminit();
        !           223: 
        !           224:     /*
        !           225:      * Good {morning,afternoon,evening,night}.
        !           226:      */
        !           227:     panic_init();
        !           228: 
        !           229:     printf(version);
        !           230: 
        !           231: #define MEG    (1024*1024)
        !           232:     printf("physical memory = %d.%d%d megabytes.\n",
        !           233:        mem_size/MEG,
        !           234:        ((mem_size%MEG)*10)/MEG,
        !           235:        ((mem_size%(MEG/10))*100)/MEG);
        !           236: 
        !           237:     /*
        !           238:      * Allocate space for system data structures.
        !           239:      * The first available real memory address is in "firstaddr".
        !           240:      * The first available kernel virtual address is in "v".
        !           241:      * As pages of kernel virtual memory are allocated, "v" is incremented.
        !           242:      * As pages of memory are allocated and cleared,
        !           243:      * "firstaddr" is incremented.
        !           244:      * An index into the kernel page table corresponding to the
        !           245:      * virtual memory address maintained in "v" is kept in "mapaddr".
        !           246:      */
        !           247: 
        !           248:     /*
        !           249:      * Since the virtual memory system has already been set up,
        !           250:      * we cannot bypass it to allocate memory as the old code
        !           251:      * DOES.  we therefore make two passes over the table
        !           252:      * allocation code.  The first pass merely calculates the
        !           253:      * size needed for the various data structures.  The
        !           254:      * second pass allocates the memory and then sets the
        !           255:      * actual addresses.  The code must not change any of
        !           256:      * the allocated sizes between the two passes.
        !           257:      */
        !           258:     firstaddr = round_page(firstaddr);
        !           259:     map_size = buffer_map_sizer();
        !           260: 
        !           261:     /*
        !           262:      * Between the following find, and the next one below
        !           263:      * we can't cause any other memory to be allocated.  Since
        !           264:      * below is the first place we really need an object, it
        !           265:      * will cause the object zone to be expanded, and will
        !           266:      * use our memory!  Therefore we allocate a dummy object
        !           267:      * here.  This is all a hack of course.
        !           268:      */
        !           269:     ret = vm_map_find(kernel_map, vm_object_allocate(0), (vm_offset_t) 0,
        !           270:                &firstaddr, map_size, TRUE);
        !           271:     ASSERT(ret == KERN_SUCCESS);
        !           272:     vm_map_remove(kernel_map, firstaddr, firstaddr + map_size);
        !           273: 
        !           274:     /*
        !           275:      * Now allocate buffers proper.  They are different than the above
        !           276:      * in that they usually occupy more virtual memory than physical.
        !           277:      */
        !           278:     buffers = (void *)firstaddr;
        !           279:     base = bufpages / nbuf;
        !           280:     residual = bufpages % nbuf;
        !           281: 
        !           282:     /*
        !           283:      * Allocate virtual memory for buffer pool.
        !           284:      */
        !           285:     buffer_map = kmem_suballoc(kernel_map,
        !           286:                               &firstaddr, &buffer_max, map_size, TRUE);
        !           287:     ret = vm_map_find(buffer_map, 
        !           288:                      vm_object_allocate(map_size), (vm_offset_t) 0,
        !           289:                      &firstaddr, map_size, FALSE);
        !           290: 
        !           291:     ASSERT(ret == KERN_SUCCESS);
        !           292: 
        !           293:     for (i = 0; i < nbuf; i++) {
        !           294:        vm_size_t       thisbsize;
        !           295:        vm_offset_t     curbuf;
        !           296: 
        !           297:        /*
        !           298:         * First <residual> buffers get (base+1) physical pages
        !           299:         * allocated for them.  The rest get (base) physical pages.
        !           300:         *
        !           301:         * The rest of each buffer occupies virtual space,
        !           302:         * but has no physical memory allocated for it.
        !           303:         */
        !           304: 
        !           305:        thisbsize = page_size*(i < residual ? base+1 : base);
        !           306:        curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
        !           307:        vm_map_pageable(buffer_map, curbuf, curbuf+thisbsize, FALSE);
        !           308:     }
        !           309: 
        !           310:     {
        !           311:        register int    nbytes;
        !           312: 
        !           313:        nbytes = ptoa(bufpages);
        !           314:        printf("using %d buffers containing %d.%d%d megabytes of memory\n",
        !           315:                nbuf,
        !           316:                nbytes/MEG,
        !           317:                ((nbytes%MEG)*10)/MEG,
        !           318:                ((nbytes%(MEG/10))*100)/MEG);
        !           319: 
        !           320:        nbytes = ptoa(vm_page_free_count);
        !           321:        printf("available memory = %d.%d%d megabytes. vm_page_free_count = %x\n",
        !           322:                nbytes/MEG,
        !           323:                ((nbytes%MEG)*10)/MEG,
        !           324:                ((nbytes%(MEG/10))*100)/MEG,
        !           325:                vm_page_free_count);
        !           326:     }
        !           327: 
        !           328:     /*
        !           329:      * Initialize memory allocator and swap
        !           330:      * and user page table maps.
        !           331:      */
        !           332:     mb_map = kmem_suballoc(kernel_map,
        !           333:                (vm_offset_t *) &mbutl,
        !           334:                (vm_offset_t *) &embutl,
        !           335:                (vm_size_t) (nmbclusters * MCLBYTES),
        !           336:                FALSE);
        !           337: 
        !           338:     /*
        !           339:      * Set up buffers, so they can be used to read disk labels.
        !           340:      */
        !           341:     bufinit();
        !           342: }

unix.superglobalmegacorp.com

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