start_kernel->setup_arch->paging_init-->free_area_init_node 之 2

static void __init free_area_init_core(struct pglist_data *pgdat,
        unsigned long *zones_size, unsigned long *zholes_size)
{
    unsigned long i, j;
    int cpu, nid = pgdat->node_id;
    unsigned long zone_start_pfn = pgdat->node_start_pfn; //该节点物理起始地址对应页帧号

    pgdat->nr_zones = 0;
    init_waitqueue_head(&pgdat->kswapd_wait);
    pgdat->kswapd_max_order = 0;
    for (j = 0; j < MAX_NR_ZONES; j++) {
        struct zone *zone = pgdat->node_zones + j;
        unsigned long size, realsize;
        unsigned long batch;

        realsize = size = zones_size[j];
        if (zholes_size)
            realsize -= zholes_size[j];

        if (j == ZONE_DMA || j == ZONE_NORMAL)
            nr_kernel_pages += realsize;
        nr_all_pages += realsize;

        zone->spanned_pages = size;       //该内存页区总页数,包括孔洞页数
        zone->present_pages = realsize;  //该内存页区实际存在页数即页区总页数减去孔洞页数
        zone->name = zone_names[j];      //该内存页区名字
        spin_lock_init(&zone->lock);
        spin_lock_init(&zone->lru_lock);
        zone->zone_pgdat = pgdat;
        zone->free_pages = 0;                   //该内存页区中的空闲页数

        zone->temp_priority = zone->prev_priority = DEF_PRIORITY;

        //临时优先级和预置优先级

        batch = zone_batchsize(zone);

        for (cpu = 0; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_NUMA
            /* Early boot. Slab allocator not functional yet */
            zone->pageset[cpu] = &boot_pageset[cpu];
            setup_pageset(&boot_pageset[cpu],0);
#else
            setup_pageset(zone_pcp(zone,cpu), batch);
#endif
        }
        printk(KERN_DEBUG "  %s zone: %lu pages, LIFO batch:%lu/n",
                zone_names[j], realsize, batch);
        INIT_LIST_HEAD(&zone->active_list);
        INIT_LIST_HEAD(&zone->inactive_list);
        zone->nr_scan_active = 0;        //扫描激活内存页数
        zone->nr_scan_inactive = 0;     //扫描未激活内存页数
        zone->nr_active = 0;                 //激活内存页数
        zone->nr_inactive = 0;              //未激活内存页数
        atomic_set(&zone->reclaim_in_progress, 0);
        if (!size)
            continue;

        /*
         * The per-page waitqueue mechanism uses hashed waitqueues
         * per zone.
         */
        zone->wait_table_size = wait_table_size(size); //该页区的等待队列链表结构指针
        zone->wait_table_bits =
            wait_table_bits(zone->wait_table_size);
        zone->wait_table = (wait_queue_head_t *)
            alloc_bootmem_node(pgdat, zone->wait_table_size
                        * sizeof(wait_queue_head_t));

        for(i = 0; i < zone->wait_table_size; ++i)
            init_waitqueue_head(zone->wait_table + i);

        pgdat->nr_zones = j+1;

        zone->zone_mem_map = pfn_to_page(zone_start_pfn);

        //指向该内存页区包含的所有内存页的描述结构变量起始地址
        zone->zone_start_pfn = zone_start_pfn;

        //该内存页区的物理开始地址对应的页号

        memmap_init(size, nid, j, zone_start_pfn);

        zonetable_add(zone, nid, j, zone_start_pfn, size);

        zone_start_pfn += size;

        zone_init_free_lists(pgdat, zone, zone->spanned_pages);
    }
}

 

memmap_init -->memmap_init_zone

void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
        unsigned long start_pfn)
{
    struct page *page;
    unsigned long end_pfn = start_pfn + size;
    unsigned long pfn;

    for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
        if (!early_pfn_valid(pfn))
            continue;
        if (!early_pfn_in_nid(pfn, nid))
            continue;
        page = pfn_to_page(pfn);                        //页号对应的page页描述结构
        set_page_links(page, zone, nid, pfn);      //设置页标志字
        set_page_count(page, 0);                        //设置页引用计数
        reset_page_mapcount(page);                  //设置页映射计数器
        SetPageReserved(page);                          //设置页保留位
        INIT_LIST_HEAD(&page->lru);
#ifdef WANT_PAGE_VIRTUAL
        /* The shift won't overflow because ZONE_NORMAL is below 4G. */
        if (!is_highmem_idx(zone))
            set_page_address(page, __va(pfn << PAGE_SHIFT));
#endif
    }
}

void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone,
                unsigned long size)
{
    int order;
    for (order = 0; order < MAX_ORDER ; order++) {
        INIT_LIST_HEAD(&zone->free_area[order].free_list);
        zone->free_area[order].nr_free = 0;  //设置对应连续2^n页空闲内存区描述结构的数组,此处均设置为0
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值