让找料更便捷
电子元器件
采购信息平台
生意随身带
随时随地找货
一站式电子元器件
采购平台
半导体行业观察第一站
标签:
摘要: 以前,在一些文档和代码中看到过说arm-linux的二级页表分为linux版本和硬件版本。一直觉得概念比较混乱,没有仔细研究,今天终于遇到了这个问题,不得不学习一下了。在do_page_fault()过程中,有下面函数会被调到: [c]static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval){pmdp[0] = _
在do_page_fault()过程中,有下面函数会被调到:
[c]static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval){pmdp[0] = __pmd(pmdval);pmdp[1] = __pmd(pmdval 256 * sizeof(pte_t));flush_pmd_entry(pmdp);}[/c]
它的功能是把在这一个新申请的二级页表与PMD关联起来。在这之前,pmdp指向的PMD项是空的,当前的过程正是在为它建立映射。在调用这个函数之前,已经申请好了一张4K大小的二级页表。
pmdp[0] = __pmd(pmdval); 这一行很容易理解,这是在把根据pte生成的PMD表项值赋值给PMD项。但是下面这一句是为什么呢?
首先先看一张二级页表有多大,arm-linux采用的是粗粒度二级页表映射,使用这种一映射关系,一个PMD表项下面映射/覆盖1M内存,一个PTE项下面映射/覆盖4K内存,所以一张二级表应该有1M/4K=256个表项。而一个二级表项是4字节,所以一张二级表应该占用空间256*4=1K字节。一个4K的内存页可以容纳4张二级表。
其次,关于二级页表,不知为什么内核要为一张二级页表提供两份版本(一个Linux版本,一个硬件版本)。而且两个版本的表的位置关系定义得很别扭。看pgalloc.h中的一个注释图:
从上(低地址)到下(高地址)分别是:第一张表的硬件版本、第二张表的硬件版本,第一张表的Linux版本、第二张表的Linux版本。可见,同一张表的linux版本和硬件版本是不连续的,但两张不同表的同一版本是连续的。我想,把这样的4张表放在一起,正是为了向4K的页面大小对齐,不至于浪费空间。
这样,一切就都好理解了。上述函数中,接下来这一行:
pmdp[1] = __pmd(pmdval 256 * sizeof(pte_t));
正是把第二张硬件表的对应的PMD值写到接下来的一个PMD表项中去。
这个函数实际上是完成了两张二级表的映射。
上一篇:已经是第一篇
型号 | 厂商 | 价格 |
---|---|---|
EPCOS | 爱普科斯 | / |
STM32F103RCT6 | ST | ¥461.23 |
STM32F103C8T6 | ST | ¥84 |
STM32F103VET6 | ST | ¥426.57 |
STM32F103RET6 | ST | ¥780.82 |
STM8S003F3P6 | ST | ¥10.62 |
STM32F103VCT6 | ST | ¥275.84 |
STM32F103CBT6 | ST | ¥130.66 |
STM32F030C8T6 | ST | ¥18.11 |
N76E003AT20 | NUVOTON | ¥9.67 |