示例#1
0
/*
 * Initialise allocator, placing addresses [@min,@max] in free pool.
 * @min and @max are PHYSICAL addresses.
 */
static void init_page_allocator(unsigned long min, unsigned long max)
{
    int i;
    unsigned long range, bitmap_size;
    chunk_head_t *ch;
    chunk_tail_t *ct;
    for ( i = 0; i < FREELIST_SIZE; i++ )
    {
        free_head[i]       = &free_tail[i];
        free_tail[i].pprev = &free_head[i];
        free_tail[i].next  = NULL;
    }

    min = round_pgup  (min);
    max = round_pgdown(max);

    /* Allocate space for the allocation bitmap. */
    bitmap_size  = (max+1) >> (PAGE_SHIFT+3);
    bitmap_size  = round_pgup(bitmap_size);
    alloc_bitmap = (unsigned long *)to_virt(min);
    min         += bitmap_size;
    range        = max - min;

    /* All allocated by default. */
    memset(alloc_bitmap, ~0, bitmap_size);
    /* Free up the memory we've been given to play with. */
    map_free(PHYS_PFN(min), range>>PAGE_SHIFT);

    /* The buddy lists are addressed in high memory. */
    min = (unsigned long) to_virt(min);
    max = (unsigned long) to_virt(max);

    while ( range != 0 )
    {
        /*
         * Next chunk is limited by alignment of min, but also
         * must not be bigger than remaining range.
         */
        for ( i = PAGE_SHIFT; (1UL<<(i+1)) <= range; i++ )
            if ( min & (1UL<<i) ) break;


        ch = (chunk_head_t *)min;
        min   += (1UL<<i);
        range -= (1UL<<i);
        ct = (chunk_tail_t *)min-1;
        i -= PAGE_SHIFT;
        ch->level       = i;
        ch->next        = free_head[i];
        ch->pprev       = &free_head[i];
        ch->next->pprev = &ch->next;
        free_head[i]    = ch;
        ct->level       = i;
    }
}
示例#2
0
void init_mm(void)
{

    unsigned long start_pfn, max_pfn;

    printk("MM: Init\n");

    arch_init_mm(&start_pfn, &max_pfn);
    /*
     * now we can initialise the page allocator
     */
    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
           (unsigned long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
           (unsigned long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
    printk("MM: done\n");

    arch_init_p2m(max_pfn);
    
    arch_init_demand_mapping_area(max_pfn);
}
示例#3
0
文件: go_mm.c 项目: unigornel/minios
static void init_page_allocator(unsigned long min, unsigned long max)
{
    mm.min_phys = round_pgup(min);
    mm.max_phys = round_pgdown(max);

    mm.bitmap_size = (mm.max_phys + 1) >> (PAGE_SHIFT + 3);
    mm.bitmap_size = round_pgup(mm.bitmap_size);
    mm.bitmap = (uint64_t *)to_virt(mm.min_phys);
    mm.min_phys += mm.bitmap_size;
    memset(mm.bitmap, ~0, mm.bitmap_size);

    mm.num_pages = (mm.max_phys - mm.min_phys) >> PAGE_SHIFT;
    bitmap_free(PHYS_PFN(mm.min_phys), mm.num_pages);

    printk("go_mm: page allocator manages %lu free pages\n", mm.num_pages);
}