super皮波 发表于 2015-01-06 17:40

关于create_mapping

体系结构arm 内核版本3.10.17
create_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

arm-linux-gcc 发表于 2015-01-06 22:05

回复 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:51

本帖最后由 super皮波 于 2015-01-07 09:55 编辑

回复 2# arm-linux-gcc

这段映射为什么只有一级映射,也就是没有pte的部分?创建完的这种一级映射之后可以直接访问内存?还是后续再创建二级的映射(pte部分),谢谢
   

arm-linux-gcc 发表于 2015-01-07 10:32

回复 3# super皮波


    low mem采用的section映射,只需要pmd就够了


arm的一级页表分为page和section,如果是section就只需要一级页表,如果是page那么就还要再去查询二级页表

super皮波 发表于 2015-01-07 10:42

回复 4# arm-linux-gcc

这块的资料去哪找呢,在网上找不到
   

arm-linux-gcc 发表于 2015-01-07 11:00

回复 5# super皮波


    arm官网的cpu手册
初次学习arm mmu/cache建议看arm920t的,因为足够简单,适合学习

如果一上来就看armv7-a的,路线太陡峭了,太多东西了,armv7-a适合对arm体系架构比较熟悉之后再看
附件是刚刚在arm官网上下载的arm920t的手册


super皮波 发表于 2015-01-07 11:14

回复 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映射(比如说代码段或者数据段中哪些部分)


   

arm-linux-gcc 发表于 2015-01-07 11:58

回复 7# super皮波


整个low mem都使用section映射
如果打开了rodata配置,那么bss所在的最后一个1M会使用page映射

其余都是page映射

humjb_1983 发表于 2015-01-07 12:41

arm-linux-gcc 发表于 2015-01-07 11:00 static/image/common/back.gif
回复 5# super皮波



arm不懂,收藏了,感谢分享~~

arm-linux-gcc 发表于 2015-01-07 12:53

回复 9# humjb_1983


    :lol ,我只熟arm架构,对x86完全不了懂
页: [1] 2 3
查看完整版本: 关于create_mapping