在哪里可以找到Linux全局mem_map数组的地址?

时间:2016-01-14 19:20:13

标签: linux kernel

我的发行版(Ubuntu 14.04.3 LTS)似乎没有导出此引用,因此我无法在模块加载时解析该地址。我正在寻找另一种方法来确定地址,而无需重新编译内核。

我在macbook pro上以VMware Fusion身份作为访客运行。内核是3.13.0-74-generic。

提前致谢

2 个答案:

答案 0 :(得分:2)

使用kallsyms_lookup_name。它在linux/kallsyms.h中定义为

unsigned long kallsyms_lookup_name(const char *name);

用法很简单:

struct page *my_mem_map = (struct page*)kallsyms_lookup_name("mem_map");
自内核2.6.33以来,

kallsyms_lookup_name被导出为模块。

对于早期的内核,或者一次查找多个符号,可以使用泛型函数kallsyms_on_each_symbol。它迭代所有符号并为它们调用用户指定的函数。

答案 1 :(得分:1)

也许这个答案对你来说太迟了@owenh。我正在为那些正在寻找有关mem_map数组的相同问题的人回答这个问题。因为到目前为止,我找不到任何关于无法找到mem_map的明确答案。在追溯pte_page的工作原理之后,我会记录我在这里学到的东西。

如果你找不到mem_map数组,那么因为内核使用了几乎连续的mem_map或者使用了sparse memory model,所以两者都没有  物理上连续的mem_map数组。相反,它可能会以vmemmapmem_section作为查找所有page struct的起点。这由CONFIG_FLATMEM/DISCONTIGMEM/CONFIG_SPARSEMEM_VMEMMAP/CONFIG_SPARSEMEM中的这些宏(include/asm-generic/memory_model.h)决定。您可以使用

之类的内容检查内核编译配置标志
sudo cat /boot/config-`uname -r` |grep CONFIG_SPARSEMEM_VMEMMAP

CONFIG_SPARSEMEM_VMEMMAP模式下,page struct数组从vmemmap开始,vmemmap位于固定位置0xffffea0000000000。

#define VMEMMAP_START    _AC(0xffffea0000000000, UL)
#define vmemmap ((struct page *)VMEMMAP_START)

CONFIG_SPARSEMEM模式下,page struct数组通过名为mem_section的二维数组进行管理。

为了了解内核如何使用它,我们可以了解内核如何获得给定页面page struct的页面的pte。此宏称为pte_page(在arch/x86/include/asm/pgtable.h中)。它将pte转换为pfn。使用pfn,它可以使用vmemmap或mem_section找到page struct。这是include/asm-generic/memory_model.h