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

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

unix.superglobalmegacorp.com

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