Linux 使用proc文件打印mem_映射的虚拟地址

Linux 使用proc文件打印mem_映射的虚拟地址,linux,memory,linux-kernel,kernel-module,procfs,Linux,Memory,Linux Kernel,Kernel Module,Procfs,我必须在内核中打印mem_map变量的内容 但是,当我通过发出make编译代码时,我看到: WARNING: "mem_map" [/home/babak/code/module/mem_map.ko] undefined! 发件人: 这是我包含的标题,我的理解是mem_map应该在mmzone.h中。我不明白为什么它不拾取变量 #include <linux/module.h> #include <linux/init.h> #include <linux/ke

我必须在内核中打印mem_map变量的内容

但是,当我通过发出make编译代码时,我看到:

WARNING: "mem_map" [/home/babak/code/module/mem_map.ko] undefined!
发件人:

这是我包含的标题,我的理解是mem_map应该在mmzone.h中。我不明白为什么它不拾取变量

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

#include <linux/types.h> /* size_t */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/switch_to.h>
#include <asm/uaccess.h> /* copy_from/to_user */
#include <linux/fs.h>       // for basic filesystem
#include <linux/proc_fs.h>  // for the proc filesystem
#include <linux/seq_file.h> // for sequence files
#include <linux/mmzone.h>

MODULE_LICENSE("Dual BSD/GPL");

static struct proc_dir_entry* proc_file;


/* memory map functions */
int mem_map_show(struct seq_file *m, void *v);
//virtual_to_physical
inline unsigned long virt_to_phy(unsigned long addr);

inline unsigned long virt_to_phy(unsigned long addr){
    return __pa(addr);
}


int mem_map_show(struct seq_file *m, void *v){

    int ret_val = 0;

    printk(KERN_INFO "Proc file read \n");
    ret_val =  seq_printf(m, "mem_map virt addr: %p \n", mem_map);
    ret_val += seq_printf(m, "mem_map phys addr: %lu \n",virt_to_phy((unsigned long)mem_map));
    ret_val += seq_printf(m, "mem_map phys pages: %lu \n", (long unsigned int)get_num_physpages);

    return ret_val;
}

static int mem_map_open(struct inode *inode, struct file *file){
    return single_open(file, mem_map_show, NULL);
}

struct file_operations mem_map_fops = {
    .owner = THIS_MODULE,
    .open = mem_map_open,
    .read = seq_read,
    .llseek = seq_lseek,
    .release = single_release,
};

static int __init mem_map_init(void){
    printk(KERN_INFO "Loaded mem_map module\n");
    proc_file = proc_create("mem_map", 0, NULL, &mem_map_fops);
    if(!proc_file){
        printk(KERN_ALERT "Error: Could not initialize /proc/mem_map");
        return -ENOMEM;
    }   
    return 0;
}

static void __exit mem_map_exit(void){
    remove_proc_entry("mem_map",NULL);  
    printk(KERN_INFO "Proc file unloaded \n");
}


/* Declaration of the init and exit functions */
module_init(mem_map_init);
module_exit(mem_map_exit);
#包括
#包括
#包括
#包括/*尺寸*/
#包括/*O_ACCMODE*/
#包括
#包括/*从/向用户复制*/
#包含//用于基本文件系统
#proc文件系统的include//
#包含//用于序列文件
#包括
模块许可证(“双BSD/GPL”);
静态结构proc_dir_条目*proc_文件;
/*内存映射函数*/
int mem_map_show(结构顺序文件*m,void*v);
//虚拟到物理
内联无符号长虚拟到物理(无符号长地址);
内联无符号长虚拟到物理(无符号长地址){
返回(地址);
}
int mem_map_show(结构顺序文件*m,void*v){
int ret_val=0;
printk(KERN_INFO“Proc file read\n”);
ret_val=seq_printf(m,“mem_map virt addr:%p\n”,mem_map);
ret_val+=seq_printf(m,“内存映射物理地址:%lu\n”,虚拟物理((无符号长)内存映射));
ret_val+=seq_printf(m,“mem_映射物理页面:%lu\n”,(长无符号int)get_num_physages);
返回返回值;
}
静态int mem_map_open(结构索引节点*索引节点,结构文件*文件){
返回单个打开(文件,内存映射显示,空);
}
结构文件\u操作mem\u映射\u fops={
.owner=此_模块,
.open=mem\u map\u open,
.read=seq_read,
.llseek=seq_lseek,
.release=单次发布,
};
静态int\uu init mem\u map\u init(void){
printk(KERN_INFO“加载的内存映射模块”\n);
proc_file=proc_create(“mem_map”,0,NULL,&mem_map\u fops);
如果(!proc_文件){
printk(KERN_警报“错误:无法初始化/proc/mem_映射”);
return-ENOMEM;
}   
返回0;
}
静态无效\退出内存\映射\退出(无效){
删除进程条目(“内存映射”,NULL);
printk(KERN_INFO“卸载的过程文件”\n);
}
/*初始化和退出函数的声明*/
模块初始化(内存映射初始化);
模块退出(内存映射退出);

链接器阶段的警告,如

WARNING: "mem_map" [/home/babak/code/module/mem_map.ko] undefined!
表示声明了
mem_map
,但模块无法访问其定义

因此,您需要在源(
.c
文件)中使用类似
EXPORT\u SYMBOL(mem\u map)
EXPORT\u SYMBOL\u GPL(mem\u map)
的搜索语句

发现对于内核3.19(
mm/memory.c
):

可能您还没有配置内核的多个节点的配置集,所以symbol
mem\u map
没有导出(甚至没有定义)

WARNING: "mem_map" [/home/babak/code/module/mem_map.ko] undefined!
#ifndef CONFIG_NEED_MULTIPLE_NODES
/* use the per-pgdat data instead for discontigmem - mbligh */
unsigned long max_mapnr;
struct page *mem_map;

EXPORT_SYMBOL(max_mapnr);
EXPORT_SYMBOL(mem_map);
#endif