create_mapping如何创建内存映射表
来源:互联网 发布:ubuntu ntfs支持 编辑:程序博客网 时间:2024/06/06 09:35
http://blog.csdn.net/huyugv_830913/article/details/5884628
1 ARM920T的MMU工作原理
下图显示了MMU地址转化关系
一级表项的地址(pmd) = ( (TLB) & (0xFFFFC000) ) + ( (Table Index)<<2 );
注1:TLB(Translate table base),即转换表基地址
注2:由于每个表项占32位(4Bytes),因此(Table Index)<<2
一级表项的内容(*pmd) = ( (pte) & (0xFFFFFC00) ) + prot_l1;
-------------------------------------------------------------------------------------
二级表项的地址(pte) = ( (pte) & (0xFFFFFC00) ) + ( (L2 table index) <<2 );
二级表项的内容(*pte) = ( (PA) & (0xFFFFF000) ) + prot_pte;
2 create_mapping分析
//利用该函数可以为物理地址创建内存的静态映射
static void __init create_mapping(struct map_desc *md)
{
...
pgd = pgd_offset_k(addr);
//计算pgd的地址(64bits) = ((mm)->pgd+pgd_index(addr))
// = ((mm)->pgd+((addr) >> 21) )
//pmd地址(32bits) = ((mm)->pgd+((addr) >> 20) )
end = addr + length;
//PGDIR_SIZE=(1UL << PGDIR_SHIFT)=2M
//一次处理2个连续的一级表项:2*1M = 2M
do {
unsigned long next = pgd_addr_end(addr, end);
alloc_init_section(pgd, addr, next, phys, type);
phys += next - addr;
addr = next;
} while (pgd++, addr != end);
}
//尝试使用段映射
static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
unsigned long end, unsigned long phys,
const struct mem_type *type)
{
pmd_t *pmd = pmd_offset(pgd, addr); //一级表指针
//pmd地址(32bits) = ((mm)->pgd+((addr) >> 20) )
/* 当大小和地址1MB对齐时,使用段映射 */
if (((addr | end | phys) & ~SECTION_MASK) == 0) {
pmd_t *p = pmd;
if (addr & SECTION_SIZE)
pmd++;
do {
*pmd = __pmd(phys | type->prot_sect);
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
//2MB,循环2次
flush_pmd_entry(p);
} else {
/* 使用small页映射,必须为二级表分配空间4Kb(1page) */
alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
}
}
//small页映射
static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
const struct mem_type *type)
{
pte_t *pte; //二级表指针
//当一级表项内容为空时,为二级表项分配空间2*512*4 = 4Kb(1Page)
if (pmd_none(*pmd)) {
pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
__pmd_populate(pmd, __pa(pte) | type->prot_l1);
//给一级表项赋值,pmd为指针,指向需赋值的地址
//pmdp[0] = __pmd(pmdval);
//pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
}
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);
//2MB,2Mb/4Kb = 512次(最多)
}
.macro armv3_set_pte_ext wc_disable=1
str r1, [r0], #-2048 @ linux version MMU看到的h/w pte0/1
eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
bic r2, r2, #PTE_TYPE_MASK
orr r2, r2, #PTE_TYPE_SMALL
tst r3, #L_PTE_USER @ user?
orrne r2, r2, #PTE_SMALL_AP_URO_SRW @设置SVC模式为读写,USR模式为READONLY
tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty?
orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
设置SVC模式为读写,USR模式为不能读,PTE_SMALL_AP_URO_SRW | PTE_SMALL_AP_UNO_SRW为SVC & USR可读写
#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
L_PTE_WRITE)
#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC
PAGE_SHARED 使用PAGE_SHARE映射的空间USR模式也能进行读写
关于读写的权限,参考ARM V5 reference.pdf 协处理器的C3寄存器和PTE的APx(3~0),PMD的domain参数
tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
movne r2, #0
.if /wc_disable
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
tst r2, #PTE_CACHEABLE
bicne r2, r2, #PTE_BUFFERABLE
#endif
.endif
str r2, [r0] @ hardware version
.endm
3 Linux MMU
#define PTRS_PER_PTE512 { (h/w + s/w ) * 4byte = 4096 }
#define PTRS_PER_PMD 1
#define PTRS_PER_PGD 2048
4 9260EK 内存映射情况
Author: WoodPecker <Pecker.hu@gmail.com>
- create_mapping如何创建内存映射表
- create_mapping如何创建内存映射表
- create_mapping如何创建内存映射表
- Linux内存分析(3) -- create_mapping
- create_mapping
- 创建内存映射文件
- 使用CreateFileMapping,MapViewOfFile创建内存映射文件,如何向内存映射文件中写入数据,读取数据。
- 如何创建内存映射文件,并对其进行写入与读取数据
- 创建进程间共享内存映射
- 如何将文件映射到内存
- Myeclipse如何自动创建hibernate以及配置struts2以及数据库表创建映射文件 详解
- iOS内存优化--大文件如何处理,内存映射
- 页表及内存映射
- 页表及内存映射
- 共享内存的创建和映射shmget()和shmat()
- 共享内存的创建和映射shmget()和shmat()
- 内存映射
- 内存映射
- HDOJ 3389 Game (博弈:Staircase Nim)
- flex3和flex4的区别【转帖】
- 黑马程序员_java基础11-GUI
- java报表软件FineReport参数界面控件默认值逻辑优化
- BOM && DOM
- create_mapping如何创建内存映射表
- CentOS/Linux 开放80、8080端口或者开放某个端口
- Windows用cygwin和mingw编译librecad
- 国内报表工具大全
- Windows server 的 Access based Enumeration
- commons-logging日志工具[续。。。。。。]
- hadoop解决问题集锦
- 关于职业规划
- C,C++表达式求值顺序