pagetable_init

见文件arch/i386/mm/init.c,初始化页面表。

实质上是重新设置swapper_pg_dir关于内核部分以上线性地址的页面表。swapper_pg_dir的物理偏移0xC00到0xFFF,即索引偏移从0x300到0x400的页面表内容。

注意此时为页面表分配内存使用alloc_bootmem_low_pages来进行,最后在分配的页面表中填写个页面描述符,即页面号对应的物理地址和属性。

我们实质上可以知道,从页表中页描述符仍然是类似0x1007、0x2007,直到(max_low_pfn<< PAGE_SHIFT)+PAGE_KERNEL这样的数据。

pagetable_init();

       kernel_physical_mapping_init (pgd_base);这里pgd_base = swapper_pg_dir

           pgd_idx = pgd_index(PAGE_OFFSET);取内核虚拟地址启始的前10位,0xC0000000的前十位,为0x300

           pgd = pgd_base + pgd_idx;即swapper_pg_dir 的第0x300项页表索引地址

           pfn = 0;

           for (; pgd_idx < PTRS_PER_PGD ; pgd++, pgd_idx++) { ;PTRS_PER_PGD=1024,从第0x300到第0xFFF项页表地址

                 pmd = one_md_table_init(pgd);

                            pud = pud_offset(pgd, 0);

                            pmd_table = pmd_offset(pud, 0);这主要是为3级页面映射做的处理,在二级映射时pmd=pgd

                 if (pfn >= max_low_pfn)

                            continue;如果设置的页面数目已经超过实际物理内存页面数目,则跳过不做设置了

                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) { ;二级映射时PTRS_PER_PMD=1

                             pte = one_page_table_init(pmd);初始化页面表

                                        if (!(pmd_val(*pmd) & _PAGE_PRESENT)) {;如果P位不为1,则指定的页面不在物理内存里,需要重新分配

                                                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);分配一个页面内存

                                                 set_pmd(pmd, pmd(pa(page_table) | _PAGE_TABLE));设置此物理内存页面属性,并将内容保存到pmd指向地址中

                                       }

                                        return pte_offset_kernel(pmd, 0);将pmd最后12位去除,获得pte页面表地址

                            for (pte_ofs = 0;pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;pte++, pfn++, pte_ofs++, address += PAGE_SIZE)

                            {;PTRS_PER_PTE=1024,保存1024个页描述符         

                                  set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));设置页号和页描述符属性,并将内容保存到pte指向地址中

                            }

               }

   } ;

这样将内核部分的页面映射在实际物理页面max_low_pfn范围内都已经设置完成。

另外由于在编译内核时定义了一些特殊常量,并在启动时分配从在编译内核时定义了一些特殊常量,并在启动时分配了从 end_of_fixed_addresses一直到0xFFFFF000的虚拟地址空间,为了保证今后使用时vmalloc(虚拟地址在1G的最后 128M空间)不会出现叠合,在这里需要做一些处理。

vaddr = fix_to_virt(end_of_fixed_addresses - 1) & PMD_MASK;获得end_of_fixed_addresses的页表索引

end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;获得FIXADDR_TOP=0xFFFFF000的页表索引

page_table_range_init(vaddr, end, pgd_base);重新设置这一段页面,实际上确认这一段映射到物理内存

load_cr3(swapper_pg_dir);重新设置cr3 ,载入页面表索引

flush_tlb_all();

flush_tlb();使用movl %cr3,%eax;movl %eax,%cr3重新刷新高速缓存

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值