ARM Linux基本运算符综合实例(2)

通过计算可以得到,PMD_SIZE产生的值为2的21次方,即为2M,PMD_MASK产生的值为0Xffe00000.

PGDIR_SHIFT是全局目录项所能映射的区域大小的对数,PGDIR_SIZE宏是用于计算页全局目录中一个单独表项所能映射区域的大小,它与PMD_SIZE一样。(用户通常可以使用减1取反来产生某个数的掩码)

有了前面基础知识的理解和掌握后,下面来介绍ARM-Linux中真正的页面映射部分的内容,着重从语法角度来介绍。

下面这个函数是嵌入式Linux中非常重要的一个函数,它用于创建页面映射,其源代码位于<arch\arm\mm\mm-armv.c>中,该函数中的关键代码如下所示:

static void _init create_mapping(struct map_desc *md){

unsigned long virt,length;

int prot_set,prot_11,domain;

pgprot_t prot_pte;

long off;

...

/*虚拟地址*/

virt = md->virtual;

/*地址偏移*/

off = md->physical - virt;

/*地址长度*/

length = md->length;

...

/*while1:判断虚拟地址是否与1M对齐,并且其长度大于页面大小*/

while((virt & 0xfffff || (virt+off) & 0xfffff) && length >=PAGE_SIZE){

/*分配中间页表项映射*/

alloc_init_page(virt,virt + off,prot_11,prot_pte);

/*虚拟地址增加PAGE_SEZE大小*/

virt += PAGE_SIZE;

/*长度减小PAGE_SIZE大小*/

length -=PAGE_SIZE;

}

/*while2:判断长度是否大于全局页表项大小的一半*/

while(length >= (PGDIR_SIZE / 2)){

/*逐段建立单层映射*/

alloc_init_section(virt,virt + off, prot_sect);

/*虚拟地址增加PGDIR_SIZE/2大小*/

virt += (PGDIR_SIZE /2);

/*长度减小PGDIR_SIZE/2大小*/

length -=(PGDIR_SIZE /2);

}

/*while3:判断长度是否大于页大小*/

while(length >= PAGE_SIZE){

/*分配中间页表项映射*/

alloc_init_page(virt,virt + off,prot_11,prot_pte);

/*虚拟地址增加PAGE_SIZE大小*/

virt +=PAGE_SIZE;

/*长度减小PAGE_SIZE大小*/

length -=PAGE_SIZE;

}

}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxjfy.html