Annotation of Net2/vm/vm_kern.c, revision 1.1.1.4

1.1       root        1: /* 
                      2:  * Copyright (c) 1991 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * The Mach Operating System project at Carnegie-Mellon University.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)vm_kern.c   7.4 (Berkeley) 5/7/91
                     37:  *
                     38:  *
                     39:  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
                     40:  * All rights reserved.
                     41:  *
                     42:  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
                     43:  * 
                     44:  * Permission to use, copy, modify and distribute this software and
                     45:  * its documentation is hereby granted, provided that both the copyright
                     46:  * notice and this permission notice appear in all copies of the
                     47:  * software, derivative works or modified versions, and any portions
                     48:  * thereof, and that both notices appear in supporting documentation.
                     49:  * 
                     50:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
                     51:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
                     52:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     53:  * 
                     54:  * Carnegie Mellon requests users of this software to return to
                     55:  *
                     56:  *  Software Distribution Coordinator  or  [email protected]
                     57:  *  School of Computer Science
                     58:  *  Carnegie Mellon University
                     59:  *  Pittsburgh PA 15213-3890
                     60:  *
                     61:  * any improvements or extensions that they make and grant Carnegie the
                     62:  * rights to redistribute these changes.
                     63:  */
                     64: 
                     65: /*
                     66:  *     Kernel memory management.
                     67:  */
                     68: 
                     69: #include "param.h"
                     70: 
                     71: #include "vm.h"
                     72: #include "vm_page.h"
                     73: #include "vm_pageout.h"
                     74: #include "vm_kern.h"
                     75: 
                     76: /*
                     77:  *     kmem_alloc_pageable:
                     78:  *
                     79:  *     Allocate pageable memory to the kernel's address map.
                     80:  *     map must be "kernel_map" below.
                     81:  */
                     82: 
                     83: vm_offset_t kmem_alloc_pageable(map, size)
                     84:        vm_map_t                map;
                     85:        register vm_size_t      size;
                     86: {
                     87:        vm_offset_t             addr;
                     88:        register int            result;
                     89: 
                     90: #if    0
                     91:        if (map != kernel_map)
                     92:                panic("kmem_alloc_pageable: not called with kernel_map");
                     93: #endif 0
                     94: 
                     95:        size = round_page(size);
                     96: 
                     97:        addr = vm_map_min(map);
                     98:        result = vm_map_find(map, NULL, (vm_offset_t) 0,
                     99:                                &addr, size, TRUE);
                    100:        if (result != KERN_SUCCESS) {
                    101:                return(0);
                    102:        }
                    103: 
                    104:        return(addr);
                    105: }
                    106: 
                    107: /*
                    108:  *     Allocate wired-down memory in the kernel's address map
                    109:  *     or a submap.
                    110:  */
                    111: vm_offset_t kmem_alloc(map, size)
                    112:        register vm_map_t       map;
                    113:        register vm_size_t      size;
                    114: {
                    115:        vm_offset_t             addr;
                    116:        register int            result;
                    117:        register vm_offset_t    offset;
                    118:        extern vm_object_t      kernel_object;
                    119:        vm_offset_t             i;
                    120: 
                    121:        size = round_page(size);
                    122: 
                    123:        /*
                    124:         *      Use the kernel object for wired-down kernel pages.
                    125:         *      Assume that no region of the kernel object is
                    126:         *      referenced more than once.
                    127:         */
                    128: 
                    129:        addr = vm_map_min(map);
                    130:        result = vm_map_find(map, NULL, (vm_offset_t) 0,
                    131:                                 &addr, size, TRUE);
                    132:        if (result != KERN_SUCCESS) {
                    133:                return(0);
                    134:        }
                    135: 
                    136:        /*
                    137:         *      Since we didn't know where the new region would
                    138:         *      start, we couldn't supply the correct offset into
                    139:         *      the kernel object.  Re-allocate that address
                    140:         *      region with the correct offset.
                    141:         */
                    142: 
                    143:        offset = addr - VM_MIN_KERNEL_ADDRESS;
                    144:        vm_object_reference(kernel_object);
                    145: 
                    146:        vm_map_lock(map);
                    147:        vm_map_delete(map, addr, addr + size);
                    148:        vm_map_insert(map, kernel_object, offset, addr, addr + size);
                    149:        vm_map_unlock(map);
                    150: 
                    151:        /*
                    152:         *      Guarantee that there are pages already in this object
                    153:         *      before calling vm_map_pageable.  This is to prevent the
                    154:         *      following scenario:
                    155:         *
                    156:         *              1) Threads have swapped out, so that there is a
                    157:         *                 pager for the kernel_object.
                    158:         *              2) The kmsg zone is empty, and so we are kmem_allocing
                    159:         *                 a new page for it.
                    160:         *              3) vm_map_pageable calls vm_fault; there is no page,
                    161:         *                 but there is a pager, so we call
                    162:         *                 pager_data_request.  But the kmsg zone is empty,
                    163:         *                 so we must kmem_alloc.
                    164:         *              4) goto 1
                    165:         *              5) Even if the kmsg zone is not empty: when we get
                    166:         *                 the data back from the pager, it will be (very
                    167:         *                 stale) non-zero data.  kmem_alloc is defined to
                    168:         *                 return zero-filled memory.
                    169:         *
                    170:         *      We're intentionally not activating the pages we allocate
                    171:         *      to prevent a race with page-out.  vm_map_pageable will wire
                    172:         *      the pages.
                    173:         */
                    174: 
                    175:        vm_object_lock(kernel_object);
                    176:        for (i = 0 ; i < size; i+= PAGE_SIZE) {
                    177:                vm_page_t       mem;
                    178: 
                    179:                while ((mem = vm_page_alloc(kernel_object, offset+i)) == NULL) {
                    180:                        vm_object_unlock(kernel_object);
                    181:                        VM_WAIT;
                    182:                        vm_object_lock(kernel_object);
                    183:                }
                    184:                vm_page_zero_fill(mem);
                    185:                mem->busy = FALSE;
                    186:        }
                    187:        vm_object_unlock(kernel_object);
                    188:                
                    189:        /*
                    190:         *      And finally, mark the data as non-pageable.
                    191:         */
                    192: 
                    193:        (void) vm_map_pageable(map, (vm_offset_t) addr, addr + size, FALSE);
                    194: 
                    195:        /*
                    196:         *      Try to coalesce the map
                    197:         */
                    198: 
                    199:        vm_map_simplify(map, addr);
                    200: 
                    201:        return(addr);
                    202: }
                    203: 
                    204: /*
                    205:  *     kmem_free:
                    206:  *
                    207:  *     Release a region of kernel virtual memory allocated
                    208:  *     with kmem_alloc, and return the physical pages
                    209:  *     associated with that region.
                    210:  */
                    211: void kmem_free(map, addr, size)
                    212:        vm_map_t                map;
                    213:        register vm_offset_t    addr;
                    214:        vm_size_t               size;
                    215: {
                    216:        (void) vm_map_remove(map, trunc_page(addr), round_page(addr + size));
1.1.1.4 ! root      217:        vm_map_simplify(map, addr);
1.1       root      218: }
                    219: 
                    220: /*
                    221:  *     kmem_suballoc:
                    222:  *
                    223:  *     Allocates a map to manage a subrange
                    224:  *     of the kernel virtual address space.
                    225:  *
                    226:  *     Arguments are as follows:
                    227:  *
                    228:  *     parent          Map to take range from
                    229:  *     size            Size of range to find
                    230:  *     min, max        Returned endpoints of map
                    231:  *     pageable        Can the region be paged
                    232:  */
                    233: vm_map_t kmem_suballoc(parent, min, max, size, pageable)
                    234:        register vm_map_t       parent;
                    235:        vm_offset_t             *min, *max;
                    236:        register vm_size_t      size;
                    237:        boolean_t               pageable;
                    238: {
                    239:        register int    ret;
                    240:        vm_map_t        result;
                    241: 
                    242:        size = round_page(size);
                    243: 
                    244:        *min = (vm_offset_t) vm_map_min(parent);
                    245:        ret = vm_map_find(parent, NULL, (vm_offset_t) 0,
                    246:                                min, size, TRUE);
                    247:        if (ret != KERN_SUCCESS) {
                    248:                printf("kmem_suballoc: bad status return of %d.\n", ret);
                    249:                panic("kmem_suballoc");
                    250:        }
                    251:        *max = *min + size;
                    252:        pmap_reference(vm_map_pmap(parent));
                    253:        result = vm_map_create(vm_map_pmap(parent), *min, *max, pageable);
                    254:        if (result == NULL)
                    255:                panic("kmem_suballoc: cannot create submap");
                    256:        if ((ret = vm_map_submap(parent, *min, *max, result)) != KERN_SUCCESS)
                    257:                panic("kmem_suballoc: unable to change range to submap");
                    258:        return(result);
                    259: }
                    260: 
                    261: /*
                    262:  *     vm_move:
                    263:  *
                    264:  *     Move memory from source to destination map, possibly deallocating
                    265:  *     the source map reference to the memory.
                    266:  *
                    267:  *     Parameters are as follows:
                    268:  *
                    269:  *     src_map         Source address map
                    270:  *     src_addr        Address within source map
                    271:  *     dst_map         Destination address map
                    272:  *     num_bytes       Amount of data (in bytes) to copy/move
                    273:  *     src_dealloc     Should source be removed after copy?
                    274:  *
                    275:  *     Assumes the src and dst maps are not already locked.
                    276:  *
                    277:  *     Returns new destination address or 0 (if a failure occurs).
                    278:  */
                    279: vm_offset_t vm_move(src_map,src_addr,dst_map,num_bytes,src_dealloc)
                    280:        vm_map_t                src_map;
                    281:        register vm_offset_t    src_addr;
                    282:        register vm_map_t       dst_map;
                    283:        vm_offset_t             num_bytes;
                    284:        boolean_t               src_dealloc;
                    285: {
                    286:        register vm_offset_t    src_start;      /* Beginning of region */
                    287:        register vm_size_t      src_size;       /* Size of rounded region */
                    288:        vm_offset_t             dst_start;      /* destination address */
                    289:        register int            result;
                    290: 
                    291:        /*
                    292:         *      Page-align the source region
                    293:         */
                    294: 
                    295:        src_start = trunc_page(src_addr);
                    296:        src_size = round_page(src_addr + num_bytes) - src_start;
                    297: 
                    298:        /*
                    299:         *      If there's no destination, we can be at most deallocating
                    300:         *      the source range.
                    301:         */
                    302:        if (dst_map == NULL) {
                    303:                if (src_dealloc)
                    304:                        if (vm_deallocate(src_map, src_start, src_size)
                    305:                                        != KERN_SUCCESS) {
                    306:                                printf("vm_move: deallocate of source");
                    307:                                printf(" failed, dealloc_only clause\n");
                    308:                        }
                    309:                return(0);
                    310:        }
                    311: 
                    312:        /*
                    313:         *      Allocate a place to put the copy
                    314:         */
                    315: 
                    316:        dst_start = (vm_offset_t) 0;
                    317:        if ((result = vm_allocate(dst_map, &dst_start, src_size, TRUE))
                    318:                                == KERN_SUCCESS) {
                    319:                /*
                    320:                 *      Perform the copy, asking for deallocation if desired
                    321:                 */
                    322:                result = vm_map_copy(dst_map, src_map, dst_start, src_size,
                    323:                                        src_start, FALSE, src_dealloc);
                    324:        }
                    325: 
                    326:        /*
                    327:         *      Return the destination address corresponding to
                    328:         *      the source address given (rather than the front
                    329:         *      of the newly-allocated page).
                    330:         */
                    331: 
                    332:        if (result == KERN_SUCCESS)
                    333:                return(dst_start + (src_addr - src_start));
                    334:        return(0);
                    335: }
                    336: 
                    337: /*
                    338:  * Allocate wired-down memory in the kernel's address map for the higher
                    339:  * level kernel memory allocator (kern/kern_malloc.c).  We cannot use
                    340:  * kmem_alloc() because we may need to allocate memory at interrupt
                    341:  * level where we cannot block (canwait == FALSE).
                    342:  *
                    343:  * This routine has its own private kernel submap (kmem_map) and object
                    344:  * (kmem_object).  This, combined with the fact that only malloc uses
                    345:  * this routine, ensures that we will never block in map or object waits.
                    346:  *
                    347:  * Note that this still only works in a uni-processor environment and
                    348:  * when called at splhigh().
                    349:  *
                    350:  * We don't worry about expanding the map (adding entries) since entries
                    351:  * for wired maps are statically allocated.
                    352:  */
                    353: vm_offset_t
                    354: kmem_malloc(map, size, canwait)
                    355:        register vm_map_t       map;
                    356:        register vm_size_t      size;
                    357:        boolean_t               canwait;
                    358: {
                    359:        register vm_offset_t    offset, i;
                    360:        vm_map_entry_t          entry;
                    361:        vm_offset_t             addr;
                    362:        vm_page_t               m;
                    363:        extern vm_object_t      kmem_object;
                    364: 
1.1.1.4 ! root      365:        if (map != kmem_map && map != mb_map)
        !           366:                panic("kern_malloc_alloc: map != {kmem,mb}_map");
1.1       root      367: 
                    368:        size = round_page(size);
                    369:        addr = vm_map_min(map);
                    370: 
                    371:        if (vm_map_find(map, NULL, (vm_offset_t)0,
                    372:                        &addr, size, TRUE) != KERN_SUCCESS) {
1.1.1.4 ! root      373:                if (canwait) { /* XXX -- then we should wait */
        !           374:                        if (map == kmem_map)
        !           375:                                panic("kmem_malloc: kmem_map too small");
        !           376:                        else if (map == mb_map)
        !           377:                                printf("kmem_malloc: mb_map too small (can't wait)\n");
        !           378:                }
        !           379:                return 0;
1.1       root      380:        }
                    381: 
                    382:        /*
                    383:         * Since we didn't know where the new region would start,
                    384:         * we couldn't supply the correct offset into the kmem object.
                    385:         * Re-allocate that address region with the correct offset.
                    386:         */
                    387:        offset = addr - vm_map_min(kmem_map);
                    388:        vm_object_reference(kmem_object);
                    389: 
                    390:        vm_map_lock(map);
                    391:        vm_map_delete(map, addr, addr + size);
                    392:        vm_map_insert(map, kmem_object, offset, addr, addr + size);
                    393: 
                    394:        /*
                    395:         * If we can wait, just mark the range as wired
                    396:         * (will fault pages as necessary).
                    397:         */
                    398:        if (canwait) {
                    399:                vm_map_unlock(map);
                    400:                (void) vm_map_pageable(map, (vm_offset_t) addr, addr + size,
                    401:                                       FALSE);
                    402:                vm_map_simplify(map, addr);
                    403:                return(addr);
                    404:        }
                    405: 
                    406:        /*
                    407:         * If we cannot wait then we must allocate all memory up front,
                    408:         * pulling it off the active queue to prevent pageout.
                    409:         */
                    410:        vm_object_lock(kmem_object);
                    411:        for (i = 0; i < size; i += PAGE_SIZE) {
                    412:                m = vm_page_alloc(kmem_object, offset + i);
                    413: 
                    414:                /*
                    415:                 * Ran out of space, free everything up and return.
                    416:                 * Don't need to lock page queues here as we know
                    417:                 * that the pages we got aren't on any queues.
                    418:                 */
                    419:                if (m == NULL) {
                    420:                        while (i != 0) {
                    421:                                i -= PAGE_SIZE;
                    422:                                m = vm_page_lookup(kmem_object, offset + i);
                    423:                                vm_page_free(m);
                    424:                        }
                    425:                        vm_object_unlock(kmem_object);
                    426:                        vm_map_delete(map, addr, addr + size);
                    427:                        vm_map_unlock(map);
                    428:                        return(0);
                    429:                }
                    430: #if 0
                    431:                vm_page_zero_fill(m);
                    432: #endif
                    433:                m->busy = FALSE;
                    434:        }
                    435:        vm_object_unlock(kmem_object);
                    436: 
                    437:        /*
                    438:         * Mark map entry as non-pageable.
                    439:         * Assert: vm_map_insert() will never be able to extend the previous
                    440:         * entry so there will be a new entry exactly corresponding to this
                    441:         * address range and it will have wired_count == 0.
                    442:         */
                    443:        if (!vm_map_lookup_entry(map, addr, &entry) ||
                    444:            entry->start != addr || entry->end != addr + size ||
                    445:            entry->wired_count)
                    446:                panic("kmem_malloc: entry not found or misaligned");
                    447:        entry->wired_count++;
                    448: 
                    449:        /*
                    450:         * Loop thru pages, entering them in the pmap.
                    451:         * (We cannot add them to the wired count without
                    452:         * wrapping the vm_page_queue_lock in splimp...)
                    453:         */
                    454:        for (i = 0; i < size; i += PAGE_SIZE) {
                    455:                vm_object_lock(kmem_object);
                    456:                m = vm_page_lookup(kmem_object, offset + i);
                    457:                vm_object_unlock(kmem_object);
                    458:                pmap_enter(map->pmap, addr + i, VM_PAGE_TO_PHYS(m),
                    459:                           VM_PROT_DEFAULT, TRUE);
                    460:        }
                    461:        vm_map_unlock(map);
                    462: 
                    463:        vm_map_simplify(map, addr);
                    464:        return(addr);
                    465: }
                    466: 
                    467: /*
                    468:  *     kmem_alloc_wait
                    469:  *
                    470:  *     Allocates pageable memory from a sub-map of the kernel.  If the submap
                    471:  *     has no room, the caller sleeps waiting for more memory in the submap.
                    472:  *
                    473:  */
                    474: vm_offset_t kmem_alloc_wait(map, size)
                    475:        vm_map_t        map;
                    476:        vm_size_t       size;
                    477: {
                    478:        vm_offset_t     addr;
                    479:        int             result;
                    480: 
                    481:        size = round_page(size);
                    482: 
                    483:        do {
                    484:                /*
                    485:                 *      To make this work for more than one map,
                    486:                 *      use the map's lock to lock out sleepers/wakers.
                    487:                 *      Unfortunately, vm_map_find also grabs the map lock.
                    488:                 */
                    489:                vm_map_lock(map);
                    490:                lock_set_recursive(&map->lock);
                    491: 
                    492:                addr = vm_map_min(map);
                    493:                result = vm_map_find(map, NULL, (vm_offset_t) 0,
                    494:                                &addr, size, TRUE);
                    495: 
                    496:                lock_clear_recursive(&map->lock);
                    497:                if (result != KERN_SUCCESS) {
                    498: 
                    499:                        if ( (vm_map_max(map) - vm_map_min(map)) < size ) {
                    500:                                vm_map_unlock(map);
                    501:                                return(0);
                    502:                        }
                    503: 
                    504:                        assert_wait((int)map, TRUE);
                    505:                        vm_map_unlock(map);
1.1.1.2   root      506: thread_wakeup(&vm_pages_needed); /* XXX */
1.1       root      507:                        thread_block();
                    508:                }
                    509:                else {
                    510:                        vm_map_unlock(map);
                    511:                }
                    512: 
                    513:        } while (result != KERN_SUCCESS);
                    514: 
                    515:        return(addr);
                    516: }
                    517: 
                    518: /*
1.1.1.3   root      519:  *     kmem_alloc_wired_wait
                    520:  *
                    521:  *     Allocates nonpageable memory from a sub-map of the kernel.  If the submap
                    522:  *     has no room, the caller sleeps waiting for more memory in the submap.
                    523:  *
                    524:  */
                    525: vm_offset_t kmem_alloc_wired_wait(map, size)
                    526:        vm_map_t        map;
                    527:        vm_size_t       size;
                    528: {
                    529:        vm_offset_t     addr;
                    530:        int             result;
                    531: 
                    532:        size = round_page(size);
                    533: 
                    534:        do {
                    535:                /*
                    536:                 *      To make this work for more than one map,
                    537:                 *      use the map's lock to lock out sleepers/wakers.
                    538:                 *      Unfortunately, vm_map_find also grabs the map lock.
                    539:                 */
                    540:                vm_map_lock(map);
                    541:                lock_set_recursive(&map->lock);
                    542: 
                    543:                addr = vm_map_min(map);
                    544:                result = vm_map_find(map, NULL, (vm_offset_t) 0,
                    545:                                &addr, size, FALSE);
                    546: 
                    547:                lock_clear_recursive(&map->lock);
                    548:                if (result != KERN_SUCCESS) {
                    549: 
                    550:                        if ( (vm_map_max(map) - vm_map_min(map)) < size ) {
                    551:                                vm_map_unlock(map);
                    552:                                return(0);
                    553:                        }
                    554: 
                    555:                        assert_wait((int)map, TRUE);
                    556:                        vm_map_unlock(map);
                    557: thread_wakeup(&vm_pages_needed); /* XXX */
                    558:                        thread_block();
                    559:                }
                    560:                else {
                    561:                        vm_map_unlock(map);
                    562:                }
                    563: 
                    564:        } while (result != KERN_SUCCESS);
                    565: 
                    566:        return(addr);
                    567: }
                    568: 
                    569: /*
1.1       root      570:  *     kmem_free_wakeup
                    571:  *
                    572:  *     Returns memory to a submap of the kernel, and wakes up any threads
                    573:  *     waiting for memory in that map.
                    574:  */
                    575: void   kmem_free_wakeup(map, addr, size)
                    576:        vm_map_t        map;
                    577:        vm_offset_t     addr;
                    578:        vm_size_t       size;
                    579: {
                    580:        vm_map_lock(map);
                    581:        (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size));
                    582:        thread_wakeup((int)map);
                    583:        vm_map_unlock(map);
1.1.1.4 ! root      584:        vm_map_simplify(map, addr);
1.1       root      585: }
                    586: 
                    587: /*
                    588:  *     kmem_init:
                    589:  *
                    590:  *     Initialize the kernel's virtual memory map, taking
                    591:  *     into account all memory allocated up to this time.
                    592:  */
                    593: void kmem_init(start, end)
                    594:        vm_offset_t     start;
                    595:        vm_offset_t     end;
                    596: {
                    597:        vm_offset_t     addr;
                    598:        extern vm_map_t kernel_map;
                    599: 
                    600:        addr = VM_MIN_KERNEL_ADDRESS;
                    601:        kernel_map = vm_map_create(pmap_kernel(), addr, end, FALSE);
                    602:        (void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0,
                    603:                                &addr, (start - VM_MIN_KERNEL_ADDRESS),
                    604:                                FALSE);
                    605: }

unix.superglobalmegacorp.com

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