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

来源:互联网 发布:puppy linux安装到u盘 编辑:程序博客网 时间:2024/05/16 10:06

上节中描述了bootmem_init()函数的总体过程,接下来具体分析其中包含的几个重要函数。

 

static unsigned int __init
find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
{
    unsigned int i, bootmem_pages = 0, memend_pfn = 0;

    for (i = 0; i < MAX_NUMNODES; i++) {    //MAX_NUMNODES = 1
        np[i].start = -1U;
        np[i].end = 0;
        np[i].bootmap_pages = 0;
    }

    for (i = 0; i < mi->nr_banks; i++) {    //mi->nr_banks = 1
        unsigned long start, end;
        int node;

        if (mi->bank[i].size == 0) {
            /*
             * Mark this bank with an invalid node number
             */
            mi->bank[i].node = -1;        //将bank size对应为0的node值均设置为-1
            continue;
        }

        node = mi->bank[i].node;

        /*
         * Make sure we haven't exceeded the maximum number of nodes
         * that we have in this configuration.  If we have, we're in
         * trouble.  (maybe we ought to limit, instead of bugging?)
         */
        if (node >= MAX_NUMNODES)
            BUG();
        node_set_online(node);

        /*
         * Get the start and end pfns for this bank
         */
        start = mi->bank[i].start >> PAGE_SHIFT;
        end   = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;

        if (np[node].start > start)
            np[node].start = start;

        if (np[node].end < end)
            np[node].end = end;

        if (memend_pfn < end)
            memend_pfn = end;
    }

    /*
     * Calculate the number of pages we require to
     * store the bootmem bitmaps.
     */
    for_each_online_node(i) {
        if (np[i].end == 0)
            continue;

        np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
                                np[i].start);
        bootmem_pages += np[i].bootmap_pages;
    }

    high_memory = __va(memend_pfn << PAGE_SHIFT);

    /*
     * This doesn't seem to be used by the Linux memory
     * manager any more.  If we can get rid of it, we
     * also get rid of some of the stuff above as well.
     *
     * Note: max_low_pfn and max_pfn reflect the number
     * of _pages_ in the system, not the maximum PFN.
     */
    max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
    max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);

    return bootmem_pages;
}

 

unsigned long __init bootmem_bootmap_pages (unsigned long pages)
{
    unsigned long mapsize;

    mapsize = (pages+7)/8;       //一个字节8位可以表示8个页面的页帧位码
    mapsize = (mapsize + ~PAGE_MASK) & PAGE_MASK;
    mapsize >>= PAGE_SHIFT;    //内存空间对应的页位码表需要多少物理页来存储

    return mapsize;
}