start_kernel->setup_arch->paging_init->bootmem_init() 之 4

来源:互联网 发布:linux的vi怎么编辑 编辑:程序博客网 时间:2024/06/05 15:59

/*
* Reserve the various regions of node 0
*/
static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
{
    pg_data_t *pgdat = NODE_DATA(0);
    unsigned long res_size = 0;

    /*
     * Register the kernel text and data with bootmem.
     * Note that this can only be in node 0.
     */
#ifdef CONFIG_XIP_KERNEL
    reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
#else
    reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);  //内核代码所占据的物理空间
#endif

    /*
     * Reserve the page tables.  These are already in use,
     * and can only be in node 0.
     */
    reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),                 //虚拟地址,物理地址映射目录所占据的物理空间
                 PTRS_PER_PGD * sizeof(pgd_t));

    /*
     * And don't forget to reserve the allocator bitmap,
     * which will be freed later.
     */
    reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,      //页帧位码表所占据的物理空间
                 bootmap_pages << PAGE_SHIFT);

    /*
     * Hmm... This should go elsewhere, but we really really need to
     * stop things allocating the low memory; ideally we need a better
     * implementation of GFP_DMA which does not assume that DMA-able
     * memory starts at zero.
     */
    if (machine_is_integrator() || machine_is_cintegrator())
        res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;

    /*
     * These should likewise go elsewhere.  They pre-reserve the
     * screen memory region at the start of main system memory.
     */
    if (machine_is_edb7211())
        res_size = 0x00020000;
    if (machine_is_p720t())
        res_size = 0x00014000;

#ifdef CONFIG_SA1111
    /*
     * Because of the SA1111 DMA bug, we want to preserve our
     * precious DMA-able memory...
     */
    res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
#endif
    if (res_size)
        reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
}

 

reserve_bootmem_node -->reserve_bootmem_core

static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
{
    unsigned long i;
    /*
     * round up, partially reserved pages are considered
     * fully reserved.
     */
    unsigned long sidx = (addr - bdata->node_boot_start)/PAGE_SIZE;      //要设置的起始页帧位码号
    unsigned long eidx = (addr + size - bdata->node_boot_start +             //要设置的终止页帧位码号
                            PAGE_SIZE-1)/PAGE_SIZE;
    unsigned long end = (addr + size + PAGE_SIZE-1)/PAGE_SIZE;

    BUG_ON(!size);
    BUG_ON(sidx >= eidx);
    BUG_ON((addr >> PAGE_SHIFT) >= bdata->node_low_pfn);
    BUG_ON(end > bdata->node_low_pfn);

    for (i = sidx; i < eidx; i++)
        if (test_and_set_bit(i, bdata->node_bootmem_map)) {                    //将相应的页帧位码表置为1
#ifdef CONFIG_DEBUG_BOOTMEM
            printk("hm, page %08lx reserved twice./n", i*PAGE_SIZE);
#endif
        }
}

原创粉丝点击