Annotation of kernel/machdep/i386/unix_startup.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) 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.