start_kernel()之page_address_init()

[start_kernel() --> page_address_init()]

page_address_init() do nothing when all RAM can be mapped directly, otherwise, do following operations:

 highmem.c:

static struct page_address_map page_address_maps[LAST_PKMAP];

void __init page_address_init(void)
{
    int i;

    INIT_LIST_HEAD(&page_address_pool);
    for (i = 0; i < ARRAY_SIZE(page_address_maps); i++)
        list_add(&page_address_maps[i].list, &page_address_pool);
    for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) {
        INIT_LIST_HEAD(&page_address_htable[i].lh);
        spin_lock_init(&page_address_htable[i].lock);
    }
    spin_lock_init(&pool_lock);
}


page_address_pool is a global variable defined in highmem.c

/*
 * page_address_map freelist, allocated from page_address_maps.
 */
static struct list_head page_address_pool;    /* freelist */
static spinlock_t pool_lock;            /* protects page_address_pool */


page_address_htable[] is also a global variable defined in highmem.c

/*
 * Hash table bucket
 */
static struct page_address_slot {
    struct list_head lh;            /* List of page_address_maps */
    spinlock_t lock;            /* Protect this bucket's list */
} ____cacheline_aligned_in_smp page_address_htable[1<<PA_HASH_ORDER];


There is a very important data structure: struct page_address_map, this structure's main purpose is to maintain the association of struct page and its virtual memory. However, this will be wasteful if the page has a linear association with its virtual memory. This becomes necessary when the addressing is hashed.


/*
 * Describes one page->virtual association
 */
struct page_address_map {
    struct page *page;
    void *virtual;
    struct list_head list;
};



Summary:
1. The main purpose of page_address_init() is to initiate global variable page_address_pool, which is used to support high memory that cannot be directly mapped.

page_address_pool is a list header pointing to lots of struct page_address_map connected each other using list.

2. page_address_htable[] is used to hold the list of entry that hash to the same bucket. page_address_init() initiates it.

作者: letmego163   发布时间: 2010-10-15