免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: date01

[内存管理] 预留Linux内核不能管理到的内存 [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
发表于 2014-06-25 15:40 |显示全部楼层
本帖最后由 arm-linux-gcc 于 2014-06-25 16:49 编辑

不要用alloc_bootmem,不管是nobootmem.c还是bootmem.c的实现,他们都会去从low mem分配,浪费了宝贵的low mem
建议像6楼那么做,最好尽量使用高地址的内存

如果一定要放在low mem或者只有low mem,要注意避开内核已经resever的内存区域,在MACHINE_START的reserve回调被调用之前,内核对以下区域做了reserve:
1,memblock_reserve(__pa(_stext), _end - _stext);                                           把从.text段到.bss段结尾这段区域加到memblock.reserved
2,memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE);          把初始页表所在的区域加到memblock.reserved
3,memblock_reserve(virt_to_phys(initial_boot_params), be32_to_cpu(initial_boot_params->totalsize));          把dtb所在的区域加到memblock.reserved
上述3个做了之后才轮到MACHINE_START中的reserve
你的10M最好挨着这些区域放,以便使得有尽量多的连续物理内存



另外cmdline中mem=size@address这种保留内存的方法最好不要再用了,在3.x的内核中,/dev/mem的mmap会将这种内存强制搞成uncache的——性能不好
ATAG_MEM和dtb中的memory节点与mem=这种方法是等价的,也不要用他们来保留内存。
使用memblock_reserve才显得更标准一些。







论坛徽章:
0
发表于 2014-06-25 16:15 |显示全部楼层
回复 6# wth0722

果然好专业,字体都是繁体,难道是港澳同胞?多谢


   

论坛徽章:
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
发表于 2014-06-25 16:22 |显示全部楼层
njuzhyf 发表于 2014-06-25 15:08
回复 8# humjb_1983

全局的?这种名字有点不像。这种模板我看了下,好像只在3个架构中实现了(arc, arm ...

没去看代码,但这里确实有点怪~

论坛徽章:
0
发表于 2014-06-25 16:31 |显示全部楼层
回复 4# njuzhyf

六楼的办法就是对启动代码的改动吧


   

论坛徽章:
0
发表于 2014-06-25 16:34 |显示全部楼层
回复 11# arm-linux-gcc

确实高端内存对于我这只是存几乎不改动的文件的需求是最好的选择




   

论坛徽章:
0
发表于 2014-06-25 16:51 |显示全部楼层
回复 14# date01

要注意你的架构。6楼的方法不是所有架构都实现了的。

其实你要做的很简单,既然都修改内核了,那就定义一个全局变量。在内核启动的时候,用memblock分配器给你找出一个10MB的空间(如memblock_find_in_range),找到的内存的其实物理地址就放在你定义的那个全局变量里。然后用memblock_reserve这段内存就行了。
   

论坛徽章:
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
发表于 2014-06-25 16:52 |显示全部楼层
arm-linux-gcc 发表于 2014-06-25 15:40
不要用alloc_bootmem,不管是nobootmem.c还是bootmem.c的实现,他们都会去从low mem分配,浪费了宝贵的low  ...

“在3.x的内核中,/dev/mem的mmap会将这种内存强制搞成uncache的”
---不知这个目的是啥?

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
发表于 2014-06-25 17:08 |显示全部楼层
回复 17# humjb_1983


    我也没搞懂为什么

#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
                              unsigned long size, pgprot_t vma_prot)
{
        if (!pfn_valid(pfn))
                return pgprot_noncached(vma_prot);

        else if (file->f_flags & O_SYNC)
                return pgprot_writecombine(vma_prot);
        return vma_prot;
}
EXPORT_SYMBOL(phys_mem_access_prot);
#endif

就是红字那一句导致的,如果在cmdline里使用mem=来保留内存,就会走到那个分支里去

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
发表于 2014-06-25 17:12 |显示全部楼层
本帖最后由 arm-linux-gcc 于 2014-06-25 17:13 编辑

还有个需要注意的,在3.x的内核中,6楼的方法,如果你需要让你预留的内存使用cache,则不能做memblock_free和memblock_remove——只做一个memblock_reserve就行了

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
发表于 2014-06-25 22:05 |显示全部楼层
回复 11# arm-linux-gcc

#ifdef CONFIG_NO_BOOTMEM
/* We are using top down, so it is safe to use 0 here */
#define BOOTMEM_LOW_LIMIT 0
#else
#define BOOTMEM_LOW_LIMIT __pa(MAX_DMA_ADDRESS)
#endif

#define alloc_bootmem(x) \
        __alloc_bootmem(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)

使用 NO_BOOTMEM时,是从高地址往地地址查找,不会优先使用 low page!

如果没配置 NO_BOOTMEM,bootmem就是实现的 bottom up方式,这个时候使用的就是从 MAX_DMA_ADDRESS向上!

x86上的确是 16MB开始的 low page!但是 arm上是:

#ifndef CONFIG_ZONE_DMA
#define MAX_DMA_ADDRESS        0xffffffffUL
#else
#define MAX_DMA_ADDRESS        ({ \
        extern unsigned long arm_dma_zone_size; \
        arm_dma_zone_size ? \
                (PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
#endif

不一定使用 low page!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP