您的位置 首页 电路

ARM linux 树立页表进程

paging_init用来建立页表,初始化zone的memorymapvoid*zero_page;sort(meminfo.bank,meminfo.nr_banks,sizeof(…

paging_init 用来树立页表,初始化zone的memory map

void *zero_page;sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);build_mem_type_table();sanity_check_meminfo();prepare_page_table();map_lowmem();bootmem_init();devicemaps_init(mdesc);kmap_init();top_pmd = pmd_off_k(0xffff0000);/** allocate the zero page.  Note that this always succeeds and* returns a zeroed result.*/zero_page = alloc_bootmem_low_pages(PAGE_SIZE);empty_zero_page = virt_to_page(zero_page);__flush_dcache_page(NULL, empty_zero_page);

build_mem_type_table这个函数依据CPU类型,设置mem_types大局数组,mem_types数组保存了页目录和页表的特点,将来创立页目录和页表时,会用到mem_types。

sanity_check_meminfo检测判别是否需求创立highmem区,而且重建描绘内存bank的数组

VMALLOC_MIN界说了vmalloc区的开端方位(经过VMALLOC_END和vmalloc_reserve核算得出),VMALLOC_END界说了vmalloc区的完毕方位,vmalloc_reserve是体系预留给vmalloc区的巨细。

prepare_page_table这个函数会请空页目录,有两块地址空间区域是不需求铲除的,一个是kernel image,别的一个是kernel线性地址映射区

map_lowmem树立低端内存的一切页目录和页表:遍历memory bank,映射那些没有highmem符号的内存bank

bootmem_init :

1. 调用check_initrd获取initrd地点的memory bank对应的node

2. 对每一个节点:

  • 获取该node的 min(最小pfn), node_low(最大low memory pfn), node_hight(最大high memory pfn)
  • 调用bootmem_init_node初始化node,bootmem_init_node会初始化bootmem bitmap
  • 假如是node 0,那么调用reserve_node_zero为node 0 reserve的内存:内核text和data区,初始化页表区(16KB),以及swapper_pg_dir之前的一块内存(在我的机器上是4个page)
  • 假如initrd寄存在当时的node上,那么调用bootmem_reserve_initrd保存initrd占用的内存。initrd_start是initrd在开端虚拟内存地址,initrd_end是initrd完毕的虚拟内存地址。

3. 对每一个node 调用bootmem_free_node

  • 设置这个node内各个zone的巨细
  • 调用free_area_init_node:核算node的总pages数目,为这个node分配mem map,留意node内一切zone的memmap都分配在一起
  • 调用free_area_init_core:关于node内的每一个zone,进行初始化。留意这个函数present_pages是total size减去了该分区对应的memmap占用的pages,可是实际上memmap是放在node的开端方位,这儿好像不应该减去这个值

4. high_memory 是一个很古怪的变量,high_memory应该是物理内存的概念,可是high_memory变量保存的的确一个内核地址。

devicemaps_init这个函数创立device的映射,

1. 把machine vectors映射到0xffff0000处

2. 调用渠道特定的map_io,关于mx51,这个函数主要是映射mx51功用寄存器区, AIPS1 AIPS2 和SPBA0,这三个寄存器区巨细为1MB,映射后的虚拟地址分别为0xF7E00000,0xF7D00000,0xFB100000

kmap_init 创立pkmap的pgd和pte。而且让pkmap_page_table指向这个PTE page的linux p/t。一般来说kmap都是运用一个page的pte来映射高端内存到内核地址空间,关于arm来说,每个page能够寄存512个pte_t,所以pkmap的地址空间为2M。

empty zero page

依照源码注释,它是一个特定的初始化为0的页,用于COW

我的了解是,体系有时需求一个页面全零,这种情况下,并不需求分配一个全零的页面,而是让PTE指向empty_zero_page,当企图写这个page时,因为这个empty_zero_page是同享的,所以导致了COW。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/277207.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部