关于create_mapping
体系结构arm 内核版本3.10.17create_mapping->alloc_init_pud->alloc_init_pmd->__map_init_section
1.这个函数alloc_init_pmd如下,如下下述的标红部分执行的话,我看代码就只做了一次一级映射,这部分的映射是干嘛用的?
do {
/*
* With LPAE, we must loop over to map
* all the pmds for the given range.
*/
next = pmd_addr_end(addr, end);
/*
* Try a section mapping - addr, next and phys must all be
* aligned to a section boundary.
*/
if (type->prot_sect &&
((addr | next | phys) & ~SECTION_MASK) == 0 &&
!force_pages) {
__map_init_section(pmd, addr, next, phys, type);
} else {
alloc_init_pte(pmd, addr, next,
__phys_to_pfn(phys), type);
}
phys += next - addr;
} while (pmd++, addr = next, addr != end);
2.__map_init_section函数,下述标红的部分没看明白,谁给解释一下,谢谢
pmd_t *p = pmd;
#ifndef CONFIG_ARM_LPAE
/*
* In classic MMU format, puds and pmds are folded in to
* the pgds. pmd_offset gives the PGD entry. PGDs refer to a
* group of L1 entries making up one logical pointer to
* an L2 table (2MB), where as PMDs refer to the individual
* L1 entries (1MB). Hence increment to get the correct
* offset for odd 1MB sections.
* (See arch/arm/include/asm/pgtable-2level.h)
*/
if (addr & SECTION_SIZE)
pmd++;
#endif 回复 1# super皮波
force_pages,你是看的android kernel吧,主线上的是没有force_pages的
__map_init_section就是写0xc0004000 ~ 0xc0008000这一部分内核主页表,映射low mem时就是走的这个分支
alloc_init_pte这个分支必须是在low mem映射好之后才能走,因为他会去调用early_alloc,而low mem映射好之前是没有内存可供分配的,因为low mem映射好之前——也就是在head.S里就只映射了text data bss这几个段所在的section,而early_alloc是从low mem最高处开始分配内存并写,而此时虽然可以分配(因为分配动作只是写了全局结构体memblock里的某些字段),但是只要一写分配到的内存内核就会发生页异常,这样内核就起不来了
pmd++
因为alloc_init_pmd的参数pmd是按照2M对齐的(也就是偶数section),因为在取pgd时就是按2M对齐的
所以如果addr是奇数section的话,那么就需要对pmd加1才能找到正确的L1项
本帖最后由 super皮波 于 2015-01-07 09:55 编辑
回复 2# arm-linux-gcc
这段映射为什么只有一级映射,也就是没有pte的部分?创建完的这种一级映射之后可以直接访问内存?还是后续再创建二级的映射(pte部分),谢谢
回复 3# super皮波
low mem采用的section映射,只需要pmd就够了
arm的一级页表分为page和section,如果是section就只需要一级页表,如果是page那么就还要再去查询二级页表 回复 4# arm-linux-gcc
这块的资料去哪找呢,在网上找不到
回复 5# super皮波
arm官网的cpu手册
初次学习arm mmu/cache建议看arm920t的,因为足够简单,适合学习
如果一上来就看armv7-a的,路线太陡峭了,太多东西了,armv7-a适合对arm体系架构比较熟悉之后再看
附件是刚刚在arm官网上下载的arm920t的手册
回复 6# arm-linux-gcc
找到这块的资料了
The translation process always starts out in the same way, with a level one fetch. A
section-mapped access requires only a level one fetch, but a page-mapped access
requires a subsequent level two fetch.
还有一个问题就是,内核中哪些部分用section映射(比如说代码段或者数据段中哪些部分)
回复 7# super皮波
整个low mem都使用section映射
如果打开了rodata配置,那么bss所在的最后一个1M会使用page映射
其余都是page映射 arm-linux-gcc 发表于 2015-01-07 11:00 static/image/common/back.gif
回复 5# super皮波
arm不懂,收藏了,感谢分享~~ 回复 9# humjb_1983
:lol ,我只熟arm架构,对x86完全不了懂