我正在尝试打印mem_map的虚拟地址,mem_map的物理地址和结构页面的数量。 所以我尝试运行this article的代码,但似乎没有显示正确的地址。 你能告诉我怎么解决这个问题吗?
以下是执行结果。
mem_map virt addr:(null) mem_map phys addr:131941395333120 mem_map phys pages:18446744072101367984
我使用的是Ubuntu12.04(64位),内核版本是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> // for basic filesystem
#include <linux/proc_fs.h> // for the proc filesystem
#include <linux/seq_file.h> // for 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: 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);
答案 0 :(得分:0)
如果我理解正确,您希望直接从内核模块打印全局 mem_map
数组的地址。您正在寻找的指针是全局的,因此您可以在内核模块中使用it has already been exported。你所要做的就是找到它的&#39;符号
通过添加<linux/kallsyms.h>
kallsyms_lookup_name()
,您可以轻松找到导出的符号,并使用char *
来获取init
并返回其代表的符号的地址。您现在要做的就是将地址分配给空指针,可能在mem_map = (struct page *) kallsyms_lookup_name("mem_map");
函数中。
mem_map
现在,您的mem_map
指针实际指向您之后的virt_to_phy()
数组。凉。
接下来,您要声明__pa()
并在其中使用virt_to_phys()
。为什么?您只需使用asm/io.h
中已声明(并在您的情况下完全相同)的printf
。请注意,您不是要尝试打印地址,因此%lx
格式为%lu
而不是get_num_physpages
。
最后但并非最不重要的,荒谬的是,您正在检查的页数实际上是get_num_physpages
地址的十进制值,这是一个函数。如果您希望打印get_num_physpages()
的返回值,则应将其称为函数get_num_physpages
,因为现在您的代码会打印指向#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 to 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: Could 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 the init and exit functions */
module_init(mem_map_init);
module_exit(mem_map_exit);
的指针的值。
我认为您的代码看起来应该是这样的:
procfs
更具体地说,如果您想要遵守mem_map_show
中的值的打印方式,我会实现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;
}
,就像这样:
import pandas as pd
from StringIO import StringIO
data = """
productid|feature1|value1|feature2|value2|feature3|value3
100001|weight|130g|||price|$140.50
100002|weight|200g|pieces|12pcs|dimensions|150X75cm
100003|dimensions|70X30cm|price|$22.90||
100004|price|$12.90|manufacturer|ABC|calories|556Kcal
100005|calories|1320Kcal|dimensions|20X20cm|manufacturer|XYZ
"""
# simulate reading from a csv file
df= pd.read_csv(StringIO(data), sep="|")
# pivot all (productid, feature{x}, value{x}) tuples into a tabular dataframe
# and append them to the following list
converted = []
# you can construct this programmatically (out of scope for now)
mapping = {"feature1": "value1", "feature2": "value2","feature3": "value3"}
# iteritems() become items() in python3
for feature, values in mapping.iteritems():
# pivot (productid, feature{x}, value{x}) into a tabular dataframe
# columns names : feature{x}
# values: value{x}
df1 = pd.pivot_table(df, values=values, index=["productid"], columns=[feature], aggfunc=lambda x: x.iloc[0])
# remove the name from the pivoted dataframe to get a standard dataframe
df1.columns.name = None
# keep productid in the dataframe as a column
df1.reset_index(inplace=True)
converted.append(df1)
# merge all dataframe in the list converted into one dataframe
final_df1 = converted[0]
for index,df_ in enumerate(converted[1:]):
final_df1 = pd.merge(final_df1, df_, how="outer")
import numpy as np
# replace None with np.nan so groupby().first() take the first none NaN vaues
final_df1.fillna(value=np.nan, inplace=True)
# format the data to be iso to what the OP wants
final_df1 = final_df1.groupby("productid", as_index=False).first()
print(final_df1)