ARM Linux (S3C6410架构/2.6.35内核)的内存映射(三)
这一段执行完之后,页表有了,但页表还是空的,下面要给指定的表项填充内容:
[c]pte = pte_offset_kernel(pmd, addr);do {set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);pfn ;} while (pte , addr = PAGE_SIZE, addr != end);}[/c]
addr是需要映射的页面的物理地址,pte_offset_kernel(pmd, addr)计算出这个物理地址在页表中对应的位置,不过需要注意的是,这里计算出的pte值指的是这个页面所对应的页表项在硬件页表中的位置。接下来调用set_pte_ext(),这是一个依硬件而不同的函数,比如在S3C6410上,它的实现是armv6_set_pte_ext(),是在arch/arm/mm/proc-macros.S文件中用汇编代码实现的。set_pte_ext()的作用是同时填充硬件页表和内核页表。
看一下在skyeye模拟器上运行这个内核的log:
vectors = 0xc02aa000
init_mm.pgd = 0xc0004000, addr = 0xffff0000, pgd_index() = 0x7ff, PGDIR_SHIFT = 21
alloc_init_pte()
pmd is still blank, pte = 0xc02ab000
will populate pmd
__pmd_populate():
&pmdp[0] = 0xc0007ff8, pmdp[0] = 0x502ab021
&pmdp[1] = 0xc0007ffc, pmdp[1] = 0x502ab421
pmd has been populated, pte = 0xc02abfc0, pfn = 0x502aa, pfn_pte = 0x502aa34b
before set_pte_ext(): hw_pte = 0xc02ab7c0, *hw_pte = 0x0, linux_pte = 0xc02abfc0, *linux_pte = 0x0
after set_pte_ext(): hw_pte = 0xc02ab7c0, *hw_pte = 0x502aa02a, linux_pte = 0xc02abfc0, *linux_pte = 0x502aa34b
我们通过bootmem申请到的中断向量表页的位置是0xc02aa000,这已经是一个虚拟地址,但我们需要把它重新映射到指定地址0xffff0000去。在alloc_init_pte()中,首先确认PGD为空,于是申请一页内存做为页表,得到的页面是0xc02ab000,紧挨着中断向量表那一样。
接下来填充PGD。我们要映射的的目标虚拟地址是0xffff0000,它在PGD表中的序号是0xffff0000/1M=0xfff,每个PGD占4字节,而PGD表的开始位置是0xc0004000,所以0xffff0000所对应的PGD的位置是0xc0004000 ((0xffff0000/1M) * 4) =
现在页表有了,下面要做的就是填充指定的页表项。目标虚拟地址0xffff0000在Linux页表中表项的地址是0xc02abfc0,这是由pte_offset_kernel(pmd, addr)计算出来的,然后调用set_pte_ext()写入页表项,汇编代码的细节这里先不深究,只看写入的内容。最后两行打印分别是调用set_pte_ext()前后硬件页表和内核页表的内容,可以看到两张表里的内容都已经填好:
before set_pte_ext(): hw_pte = 0xc02ab7c0, *hw_pte = 0x0, linux_pte = 0xc02abfc0, *linux_pte = 0x0
after set_pte_ext(): hw_pte = 0xc02ab7c0, *hw_pte = 0x502aa02a, linux_pte = 0xc02abfc0, *linux_pte = 0x502aa34b
ARMLinuxS3C6410架构2 6 35内核内存映 相关文章:
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(四)(11-09)
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(二)(11-09)
- ARM Linux (S3C6410架构/2.6.35内核)的内存映射(五)(11-09)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- 基于TMS320DM642的农药喷洒系统(04-22)
- 用DSP56F805 PWM模块输出高频正弦波(05-25)