免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: super皮波
打印 上一主题 下一主题

[内存管理] 关于create_mapping [复制链接]

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
11 [报告]
发表于 2015-01-07 13:27 |只看该作者
回复 8# arm-linux-gcc

整个low mem? 指的是?
   

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
12 [报告]
发表于 2015-01-07 13:41 |只看该作者
回复 11# super皮波


    就是低端内存啊

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
13 [报告]
发表于 2015-01-07 13:43 |只看该作者
回复 12# arm-linux-gcc
这块做的section映射是内核刚启动的时候做的吧,启动之后还是会是page-mapped,那为什么开始的时候要搞成section映射,而不直接搞成page-mapped形式呢?
作用何在


   

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
14 [报告]
发表于 2015-01-07 14:26 |只看该作者
本帖最后由 arm-linux-gcc 于 2015-01-07 14:29 编辑

回复 13# super皮波


    low mem没有映射为page,一直都是section(我们先不考虑android kernel那个CONFIG_RODATA,你可以把force_page始终看为0)

1,head.S里面映射的不是整个low mem,因为此时还不知道物理内存的size,所以head.S中只映射了text data bss段,因为这些虚拟地址在链接时就已确定,
而物理地址则可以在打开mmu之前取当前pc,因为head.S里面内容并不多,所以当前pc必定是在首个1M里的,将这个pc丢弃低20位就能够得到物理基地址(pa_base),
所以text data bss段的物理地址也就能够算出来(va - 0xc0000000 + pa_base),
于是我们就能够知道text data bss的物理地址和虚拟地址,这样就能够建立页表了。
由于只知道text data bss的物理地址和虚拟地址,而不知道整个mem的size,所以我们无法为bss end后面的内存做映射

2,paging_init里面会对整个低端内存做映射,物理内存的size是通过bootloader传给kernel的,通过cmdline或atag_mem或dts,
由于head.S里都是汇编代码,汇编代码很难实现解析cmdline/atag_mem/dts的功能,所以这些解析都是用C代码写的,所以head.S里面没有映射bss end之后的内存,这些内存是稍后在C代码里解析并做映射的。
在paging_init里面做整个low mem的映射,这会导致text  data  bss的映射被重做一遍,只不过text data bss的那些映射关系仍然和head.S时的是一样的

3,映射成page需要更多的内存,所以没必要将Low mem这种永远固定的映射搞成二级页表

4,内核虚拟起始地址是在0xc0008000,而0xc0004000 ~ 0xc0008000是放的一级页表,0xc0000000 ~ 0xc0004000是放的atag_core atag_mem atag_cmdline,
因此没有多余的空闲内存用来放二级页表,所以只能做成section

5,二级页表本身的buffer是动态分配的,在low mem完成映射之前,没有内存可供分配,所以整个low mem必须映射成section的




论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
15 [报告]
发表于 2015-01-07 14:37 |只看该作者
回复 14# arm-linux-gcc

多谢兄弟,大致懂了,再仔细看看代码
   

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
16 [报告]
发表于 2015-01-08 11:31 |只看该作者
arm-linux-gcc 发表于 2015-01-07 14:26
回复 13# super皮波


呵呵,x86中,看似在内核页表初始化时,buddy system应该已经可用。
内核页表第一级页目录的空间是在head.S中预先分配的,后面级的页表的空间是通过buddy system动态分配的。
arm应该主要是为了节省空间?呵呵

论坛徽章:
0
17 [报告]
发表于 2015-01-08 14:03 |只看该作者
回复 14# arm-linux-gcc

linux 3.5
create_mapping-> .... -> alloc_init_pte()

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 *start_pte = early_pte_alloc(pmd);
        pte_t *pte = start_pte + pte_index(addr);

        /* If replacing a section mapping, the whole section must be replaced */
        BUG_ON(pmd_bad(*pmd) && ((addr | end) & ~PMD_MASK));

        do {
                set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
                pfn++;
        } while (pte++, addr += PAGE_SIZE, addr != end);
        early_pte_install(pmd, start_pte, type->prot_l1);
}

看代码,set_pte_ext所设置的项是linux pt,early_pte_install设置的地址是h/w 项地址.
                 linux pt 0   <- start_pte
                 linux pt 1
pmd      ->  h/w      0
pmd+4  ->   h/w      1

是不是create_mapping上进行二级映射上,所设置的是模拟表项,如果真的虚拟地址映射到的时候该表项还是为空,还是会引起页缺陷,
但是可以根据liunux pt 推出 h/w pt ?具体推出的代码在哪里呢?

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
18 [报告]
发表于 2015-01-08 16:34 |只看该作者
本帖最后由 arm-linux-gcc 于 2015-01-08 17:09 编辑

回复 17# darling54454


cpu_v7_set_pte_ext里面同时设置了linux pte和hw pte的

cpu_v7_set_pte_ext的参数无需传递hw pte值下去,只需要传递linux pte值下去就可以了
这个函数内部会根据linux pte的各个位来设置hw pte的相应位,
并且linux pte某些位和hw pte的某些位的offset相同,所以这些位直接从linux pte拷贝过来就行了,如cacheable bufferable,在linux pte里是(3<<2),而在hw pte是((1<<3)|(1<<2)),所以两者的offset相同,可以看到在cpu_v7_set_pte_ext实现里面有bic        r3, r1, #0x000003f0,低4位没有清零,所以hw pte的C位和B位直接从linux pte里得来的

论坛徽章:
0
19 [报告]
发表于 2016-04-26 00:20 |只看该作者
回复 14# arm-linux-gcc


    目前也在看类似的问题,低端内存无法通过page table walk来计算物理地址,就是pte_offset_kernel,后来跟了一下create_mapping函数,发现low memory的内存没有建立pte,只建立到pmd就完了。
    那MMU硬件怎么计算出low memory的物理地址的,直接做偏移的减法?但MMU怎么知道的,哪段地址是low memory的?
    没有看到相关code告诉MMU,只看到alloc_init_section-->flush_pmd_entry-->flush_tlb,这里只更新了tlb,并没有通知MMU一级页表的建立情况?
谢谢。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
20 [报告]
发表于 2016-04-26 19:27 |只看该作者
回复 19# wisedd


    不是MMU计算的,而是你自己的代码计算好之后,填到页表里的,MMU只管用你填好的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP