linux - How to print the information of mem_map using proc file? -


i'm trying print virtual address of mem_map,physical address of mem_map , number of struct page now. tried running code of this article,but seemed didn't show correct address. tell me how can fix this?

below result of execution.

mem_map virt addr: (null) mem_map phys addr: 131941395333120 mem_map phys pages: 18446744072101367984

i'm using ubuntu12.04(64bit) , kernel version 3.13.

#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h>  #include <asm/switch_to.h> #include <linux/types.h> /* size_t */ #include <linux/fcntl.h> /* o_accmode */ #include <asm/uaccess.h> /* copy_from/to_user */ #include <linux/fs.h>       // basic filesystem #include <linux/proc_fs.h>  // proc filesystem #include <linux/seq_file.h> // sequence files #include <linux/mm.h>  module_license("dual bsd/gpl");  static struct proc_dir_entry* proc_file; struct page *mem_map; export_symbol(mem_map);  /* 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); }  char buf[300];  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: 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 init , exit functions */ module_init(mem_map_init); module_exit(mem_map_exit); 

if understand correctly, want print address of global mem_map array, right kernel module. pointer you're looking global ,therefore it has been exported use in kernel module. have find its' symbol.

finding exported symbol easy, including <linux/kallsyms.h> you'll have power of using kallsyms_lookup_name() takes char * , returns address of symbol represents. have now, assigning address empty pointer, possibly in init function.

mem_map = (struct page *) kallsyms_lookup_name("mem_map"); 

now mem_map pointer points mem_map array you're after. cool.

next, you're declaring virt_to_phy() , using __pa() inside it. why? can use virt_to_phys() declared (and doing same in case) in asm/io.h. please not you're trying print address, therefore right printf format %lx instead of %lu.

last not least, ridiculous number of pages you're examining decimal value of address of get_num_physpages, function. if wish print return value of get_num_physpages should call function, get_num_physpages() because code prints value of pointer get_num_physpages.

this how think code should have looked like:

#include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/mm.h> #include <linux/kallsyms.h> #include <asm/io.h>  #define error -1  module_license("dual bsd/gpl");  static struct proc_dir_entry* proc_file; struct page *mem_map;  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:\t0x%p\n", mem_map);     ret_val += seq_printf(m, "mem_map phys addr:\t0x%016llx\n", ((unsigned long long) virt_to_phys((volatile void *) mem_map)));     ret_val += seq_printf(m, "mem_map phys pages:\t%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");     mem_map = (struct page *) kallsyms_lookup_name("mem_map");     if (!mem_map) {         printk(kern_alert "error: unable find address of global 'mem_map'\n");                 return error;         }     proc_file = proc_create("mem_map", 0, null, &mem_map_fops);     if (!proc_file) {         printk(kern_alert "error: not initialize /proc/mem_map\n");         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 init , exit functions */ module_init(mem_map_init); module_exit(mem_map_exit); 

and more specifically, if want comply how values in procfs printed, implement mem_map_show this:

int mem_map_show(struct seq_file *m, void *v) {     int ret_val = 0;      ret_val =  seq_printf(m, "0x%p 0x%016llx %lu\n",             mem_map,              ((unsigned long long) virt_to_phys((volatile void *) mem_map)),             (long unsigned int) get_num_physpages());     return ret_val; } 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -