分配初始化零页
1.从bootmem分配一页
/*这里zero_page指向虚拟地址*/ void *zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
2.找出zero_page对应的页框描述符page结构体
struct page * empty_zero_page = virt_to_page(zero_page);
3.flush_dcache_page(empty_zero_page);
这个函数里面涉及一些cache即buffer的硬件操作,有时间可以详细分析,有助于加深多不同类型cache的理解。
flush_dcache_page(empty_zero_page); -->struct address_space *mapping = page_mapping(page);/*这里应该返回NULL*/ -->#define PageHighMem(__p) is_highmem(page_zone(__p)) -->__flush_dcache_page(mapping, page); -->__cpuc_flush_dcache_page(page_address(page)); /*即v6_flush_kern_dcache_page in arm/arm/mm/cache-v6.S*/ -->proc_info_list->cache->flush_kern_dcache_page
这里汇编代码的作用是把缓存中的数据写到物理内存中,确保数据的一致性。
/* * v6_flush_kern_dcache_page(kaddr) * * Ensure that the data held in the page kaddr is written back * to the page in question. * * - kaddr - kernel address (guaranteed to be page aligned) */ ENTRY(v6_flush_kern_dcache_page) add r1, r0, #PAGE_SZ 1: #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line #else mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate unified line #endif add r0, r0, #D_CACHE_LINE_SIZE cmp r0, r1 blo 1b #ifdef HARVARD_CACHE mov r0, #0 mcr p15, 0, r0, c7, c10, 4 #endif mov pc, lr