金融港青年公寓怎么样:页表创建create_mapping
来源:百度文库 编辑:九乡新闻网 时间:2024/05/22 01:16:04
页表创建create_mappingLinux arch/arm/mm/mmu.c:void __init create_mapping(struct map_desc *md)
{
unsigned long phys, addr, length, end;
const struct mem_type *type;
pgd_t *pgd; //只有虚拟地址处于用户空间(只能是中断向量表)
//但又不是映射为0地址的中断向量表时报错
//只能给系统空间 或者 中断向量 所在的空间创建映射,绝对不可给用户虚拟空间创建映射。
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
"0x%08llx at 0x%08lx in user region\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
} //当类型为MT_DEVICE或者MT_ROM,但是他们的虚拟地址
//又处于vmalloc的空间(c0000000----d0000000)
//VMALLOC_END是在我们include/asm-arm/arch-sep4020/vmalloc.h中定义
//所以我们在对寄存器进行静态映射其实也是有限制的
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
"overlaps vmalloc space\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
} type = &mem_types[md->type]; //获取memory类型 /*
* Catch 36-bit addresses
*/
//以下已经超出普通嵌入式应用,忽略
if (md->pfn >= 0x100000) {
create_36bit_mapping(md, type);
return;
} addr = md->virtual & PAGE_MASK; //得到虚拟地址
phys = (unsigned long)__pfn_to_phys(md->pfn); //得到物理地址
length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); //映射长度 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
"be mapped using pages, ignoring.\n",
__pfn_to_phys(md->pfn), addr);
return;
} pgd = pgd_offset_k(addr);
end = addr + length;
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);
} 关联函数:alloc_init_section(unsigned long virt, unsigned long phys, int prot){ //pmdp是一级页表描述符的地址 pmd_t *pmdp = pmd_off_k(virt); if (virt & (1 << 20)) pmdp++; //向一级页表描述符地址中写入一级页表描述符 //一级页表描述符:12bit phys | 20 bit prot //对于内存来说打印信息为: pmdp is c0007000, value is 3000041e // pmdp is c000707c, value is 31f0041e *pmdp = __pmd(phys | prot); flush_pmd_entry(pmdp);} alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot){ pmd_t *pmdp = pmd_off_k(virt); pte_t *ptep; if (pmd_none(*pmdp)) { //对于粗颗粒小页变换,一级页表描述符是和二级页表的基地址有关的 //所以这里除了有protl1还有ptep的物理地址 ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); __pmd_populate(pmdp, __pa(ptep) | prot_l1); } //根据pmd找pte项(ptep用通俗的语言来说就是二级页表描述符地址) ptep = pte_offset_kernel(pmdp, virt); //ptep是二级页表描述符地址,pfn_pte是根据虚拟地址和配置选项得到二级页表描述符 //set_pte函数是在arch/arm/mm/proc_720t.s中实现的 set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));} /* * Function: arm720_set_pte(pte_t *ptep, pte_t pte) * Params : r0 = Address to set * : r1 = value to set * Purpose : Set a PTE and flush it out of any WB cache */ //其实这一步只是往一个二级页表描述符地址里面存放一个二级页表描述符,一个str指令就能完成的,但正是因为之前所说的在linux中有两种pte机制(linux,硬件),所以在配置完了linux的,还需要配置硬件,因此在这里第一行代码之下,都是为了实现硬件的pte的设置。 .align 5ENTRY(cpu_arm720_set_pte) str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY bic r2, r1, #PTE_SMALL_AP_MASK bic r2, r2, #PTE_TYPE_MASK orr r2, r2, #PTE_TYPE_SMALL tst r1, #L_PTE_USER @ User? orrne r2, r2, #PTE_SMALL_AP_URO_SRW tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? orreq r2, r2, #PTE_SMALL_AP_UNO_SRW tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young movne r2, #0 str r2, [r0] @ hardware version mov pc, lr
{
unsigned long phys, addr, length, end;
const struct mem_type *type;
pgd_t *pgd; //只有虚拟地址处于用户空间(只能是中断向量表)
//但又不是映射为0地址的中断向量表时报错
//只能给系统空间 或者 中断向量 所在的空间创建映射,绝对不可给用户虚拟空间创建映射。
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
"0x%08llx at 0x%08lx in user region\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
} //当类型为MT_DEVICE或者MT_ROM,但是他们的虚拟地址
//又处于vmalloc的空间(c0000000----d0000000)
//VMALLOC_END是在我们include/asm-arm/arch-sep4020/vmalloc.h中定义
//所以我们在对寄存器进行静态映射其实也是有限制的
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
"overlaps vmalloc space\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
} type = &mem_types[md->type]; //获取memory类型 /*
* Catch 36-bit addresses
*/
//以下已经超出普通嵌入式应用,忽略
if (md->pfn >= 0x100000) {
create_36bit_mapping(md, type);
return;
} addr = md->virtual & PAGE_MASK; //得到虚拟地址
phys = (unsigned long)__pfn_to_phys(md->pfn); //得到物理地址
length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); //映射长度 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
"be mapped using pages, ignoring.\n",
__pfn_to_phys(md->pfn), addr);
return;
} pgd = pgd_offset_k(addr);
end = addr + length;
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);
} 关联函数:alloc_init_section(unsigned long virt, unsigned long phys, int prot){ //pmdp是一级页表描述符的地址 pmd_t *pmdp = pmd_off_k(virt); if (virt & (1 << 20)) pmdp++; //向一级页表描述符地址中写入一级页表描述符 //一级页表描述符:12bit phys | 20 bit prot //对于内存来说打印信息为: pmdp is c0007000, value is 3000041e // pmdp is c000707c, value is 31f0041e *pmdp = __pmd(phys | prot); flush_pmd_entry(pmdp);} alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot){ pmd_t *pmdp = pmd_off_k(virt); pte_t *ptep; if (pmd_none(*pmdp)) { //对于粗颗粒小页变换,一级页表描述符是和二级页表的基地址有关的 //所以这里除了有protl1还有ptep的物理地址 ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); __pmd_populate(pmdp, __pa(ptep) | prot_l1); } //根据pmd找pte项(ptep用通俗的语言来说就是二级页表描述符地址) ptep = pte_offset_kernel(pmdp, virt); //ptep是二级页表描述符地址,pfn_pte是根据虚拟地址和配置选项得到二级页表描述符 //set_pte函数是在arch/arm/mm/proc_720t.s中实现的 set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));} /* * Function: arm720_set_pte(pte_t *ptep, pte_t pte) * Params : r0 = Address to set * : r1 = value to set * Purpose : Set a PTE and flush it out of any WB cache */ //其实这一步只是往一个二级页表描述符地址里面存放一个二级页表描述符,一个str指令就能完成的,但正是因为之前所说的在linux中有两种pte机制(linux,硬件),所以在配置完了linux的,还需要配置硬件,因此在这里第一行代码之下,都是为了实现硬件的pte的设置。 .align 5ENTRY(cpu_arm720_set_pte) str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY bic r2, r1, #PTE_SMALL_AP_MASK bic r2, r2, #PTE_TYPE_MASK orr r2, r2, #PTE_TYPE_SMALL tst r1, #L_PTE_USER @ User? orrne r2, r2, #PTE_SMALL_AP_URO_SRW tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? orreq r2, r2, #PTE_SMALL_AP_UNO_SRW tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young movne r2, #0 str r2, [r0] @ hardware version mov pc, lr
页表创建create_mapping
create_mapping如何创建内存映射表
ORACLE TABLESPACE 创建表空间
Google 快讯 - 创建校友联网页
第17章 创建工作表窗体
用VBA创建数据透视表 - 转
Origin简明教程八章:创建版面页(Layout)
oracle创建表空间和用户授权sss
oracle创建表空间和用户授权1
在Excel工作表中创建关联列表0
在Excel工作表中创建关联列表00
Oracle创建用户、表空间、导入导出、...命令
创建人脉
创建富硒菜蓝子疏菜县
创建文明城市
创建记录
创建图表
创建和谐
【创建标准】“中国最佳旅游城市”创建指南
WD2000: 如何创建带有不同首页或不同的奇偶页眉和页脚模板
快速为Excel工作簿创建工作表目录的方法
快速为Excel工作簿创建工作表目录的方法 - 电脑技术
使用Oracle可传输表空间的特性复制数据(6)RMAN备份也创建
用VBA创建数据透视表 - excelpeixun的日志 - 网易博客