Linux页表机制管理初始化

字体大小: 中小 标准 ->行高大小: 标准

linux页表机制的建立分为两个阶段,第一个阶段在启动初始化时,调用汇编代码实现临时的分页;第二阶段在内核初始化时建立完整的完整的页表机制。对于物理地址扩展(PAE)分页机制中,intel通过在她得处理器上把管脚数从32增加到36已经满足了这些需求,寻址能力可以达到64GB。不过,只有引入一种新的分页机制把32位线性地址转换为36位物理地址才能使用所增加的物理地址。linux为对多种体系的支持,选择了一套简单的通用实现机制。在这里,只分析x86 32位下的实现。

下图为一个linux分页机制框架图:

Linux页表机制管理初始化





一、临时内核页表初始化

在setup_32.S中

[cpp]
  1. page_pde_offset = (__PAGE_OFFSET >> 20);     
  2.     movl $pa(__brk_base), %edi       movl $pa(swapper_pg_dir), %edx  
  3.     movl $PTE_IDENT_ATTR, %eax   10:  
  4.     leal PDE_IDENT_ATTR(%edi),%ecx      /* Create PDE entry */       movl %ecx,(%edx)            /* Store identity PDE entry */  
  5.     movl %ecx,page_pde_offset(%edx)     /* Store kernel PDE entry */       addl $4,%edx  
  6.     movl $1024, %ecx   11:  
  7.     stosl       addl $0x1000,%eax  
  8.     loop 11b       /* 
  9.      * End condition: we must map up to the end + MAPPING_BEYOND_END.       */  
  10.     movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp       cmpl %ebp,%eax  
  11.     jb 10b       addl $__PAGE_OFFSET, %edi  
  12.     movl %edi, pa(_brk_end)       shrl $12, %eax  
  13.     movl %eax, pa(max_pfn_mapped)     
  14.     /* Do early initialization of the fixmap area */       movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax  
  15.     movl %eax,pa(swapper_pg_dir+0xffc)  

对于页表初始化的原理如果可以参考intel手册。

其中常量PTE_IDENT_ATTR定义在patable_types.h中。

[cpp]
  1. #define PTE_IDENT_ATTR   0x003      /* PRESENT+RW */  

二、启动分页机制

实现代码在head_32.S中。

[cpp]
  1. movl $pa(swapper_pg_dir),%eax   movl %eax,%cr3      /* set the page table pointer.. */  
  2. movl %cr0,%eax   orl  $X86_CR0_PG,%eax  
  3. movl %eax,%cr0      /* ..and set paging (PG) bit */  

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/57879.html