免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6774 | 回复: 7
打印 上一主题 下一主题

[进程管理] 请问:mem_map数组是什么? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-26 17:27 |只看该作者 |倒序浏览
我看《linux内核API完全参考手册》时,
说到mem_map数组的起始地址为0xC1000000,
可是我用它的例子,得出的mem_map数组的起始
却是0,请问mem_map数组是什么?
难道说它的起始地址一定是0xC1000000吗?
为什么我的却不是?

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
2 [报告]
发表于 2013-10-27 00:09 |只看该作者
回复 1# netdoger


    mem_map数组是page descriptor array. 也就是struct page类型变量的数组, 存储着所有物理页的描述符.

     这个数组和内存节点有关。  如果你的内存是单节点的, 可以通过NODE_DATA[0].node_mem_map来访问第一个节点的mem_map数组.

论坛徽章:
0
3 [报告]
发表于 2013-10-27 08:58 |只看该作者
我看到书上说:
内核用数据结构page描述一个页框的状态信息,所有的页描述符存放在全局mem_map数组中,其数组的下标为页框号(pfn)。
因为每个描述符长度为32字节,那么一个页描述符怎样与一个占据4k的页框相联系(映射)呢?有了mem_map数组,
这个问题就很简单了。因为如果知道了page数据的地址pd,用pd去减去mem_map就得到了pd的页框号pfn。

可是我对这个有疑问:
比如我的内存是1M,那么1M的内存可以分为1M/4k=256个页面,也就是说mem_map的最大下标是255,
每个页面需要32个字节的描述符,那么256个页面需要32*256个字节,也就是需要32*256/4k=2个页面,
即前面8k的内存是描述符,也就是存放mem_map的内容,即mem_map的地址是0,那么从第三个页面
可是存放数据,那么第三个页面的地址-mem_map的地址应该是8*1024,这个怎么可能是mem_map
的下标呢?
请问我这样理解有什么问题吗

论坛徽章:
0
4 [报告]
发表于 2013-10-27 10:53 |只看该作者
为什么书上说mem_map的起始地址一定是0xC1000000,可是我得出却是0?

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
5 [报告]
发表于 2013-10-27 14:03 |只看该作者
回复 3# netdoger

   这是单一节点且flat memory model时, 通过pfn查找相应的page descriptor的函数.
  
   struct page *mem_map;

  #define __pfn_to_page(pfn)      (mem_map + ((pfn) - ARCH_PFN_OFFSET))  // ARCH_PFN_OFFSET 如果没有特别配置,一般为0.

  你指的第三个page frame的page desciptor, 是从mem_map指向的内存移动了2*sizeof(struct page) 字节 不就等于  mem_map + 2。

   为什么书上说mem_map的起始地址一定是0xC1000000,可是我得出却是0?

     mm/memory.c中
#ifndef CONFIG_NEED_MULTIPL_NODES          /*UMA*/
  unsigned long max_mapnr;
  struct page *mem_map;
...
  #endif

mm/page_alloc.c中
alloc_node_mem_map()函数负责申请mem_map的内存.
这里提到:
   #ifdef CONFIG_FLAT_NODE_MEM_MAP
           ...
         map = alloc_remap(pgdat->node_id,  size);
         if (!map)
              map = alloc_bootmem_node();              // 申请分配mem_map的内存
         pgdat-> node_mem_map = map + (pgdat-> node_start_pfn - start);
#ifndef CONFIG_NEED_MULITPLE_NODES
          if (pgdat == NODE_DATA[0])){             //如果是第一个节点
                   mem_map = NODE_DATA[0]->node_mem_map;         
            .....
        }
    ...
#endif
#endif


从上面两个函数来看,都使用了条件宏. 说明mem_map不仅和内存模型有关, 而且和内存节点有关.
因此, 在某些架构中, mem_map不一定被赋值.

我个人觉得, 最好通过隐藏了底部细节的NODE_DATA(节点描述符数组)来获得mem_map的起始地址:
NODE_DATA[0]->node_mem_map.  

另外你可以通过dmesg  | grep -e 'node_mem_map'来获得 'mem_map'的地址.

论坛徽章:
0
6 [报告]
发表于 2013-10-27 16:43 |只看该作者
虽然我看得不是很明白,但是我还是要说:你牛!

论坛徽章:
0
7 [报告]
发表于 2013-10-27 16:46 |只看该作者
dmesg  | grep -e 'node_mem_map',我这样不行,没有。还能怎么样看到'node_mem_map'这个地址?
可能我装载模块时,有执行dmesg -c,把它清掉了

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
8 [报告]
发表于 2013-10-27 21:39 |只看该作者
回复 7# netdoger


    这个是在内核启动时, 打印的mem_map的地址.. 调用函数是free_area_init_node()。在系统启动时间 不到1s时 打印.
   
    如果系统长时间运行, dmesg会丢失之前记录的

     
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP