我试图使用proc
文件系统从Linux内核模块函数向用户空间写入数据。我想使用seq_file
迭代实现,因此它处理页面大小和所有好东西。我有一个不断记录数据和创建结构并使用数据填充结构的函数。我想将这些结构抽取到proc
文件系统,以便用户空间中的应用程序可以获取这些结构并适当地处理它们。当用户空间准备好接收数据时,它将从proc文件系统读取,这将关闭所有这些。我以为我无法将结构传递给seq_file show
函数。那么我可以全局声明结构并将其打印到/proc/info
函数的seq_show
文件中吗?我目前正在尝试实施。
typedef struct data_t{
unint32_t address;
unint8_t pid;
unint8_t info;
} data_t;
data_t data = NULL;
static void datalog(uint32_t addy, unint8_t info){
// this function is constantly logging data
data->address = addy;
data->info = info;
}
static void *seq_start(struct seq_file *s, loff_t *pos)
{
// seq file start stuff
}
static int seq_show(struct seq_file *s, void *v)
{
//print the data struct to the /proc/info file
return 0;
}
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
{
// move the pointer along
return v;
}
static void seq_stop(struct seq_file *s, void *v)
{
}
static struct seq_operations seq_ops = {
.start = seq_start,
.next = seq_next,
.stop = seq_stop,
.show = seq_show
};
static int open(struct inode *inode, struct file *file)
{
return seq_open(file, &seq_ops);
};
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
static int init(void)
{
struct proc_dir_entry *entry = NULL;
entry = proc_create("info", 0777, NULL, &fops);
data = (data_t *) kmalloc(sizeof(data_t), GFP_KERNEL);
return 0;
}
因此datalog
函数已经处于一个常量循环中。我想将所有这些结构抽取到/proc/info
文件中,以便可以在用户空间中对其进行适当处理。这将是快速的火灾数据,所以它不会感觉copy_to_user
是要走的路。正如你所看到的,我不确定我做了什么,所以任何方向或帮助都非常感谢!谢谢!
答案 0 :(得分:0)
假设你正在维护一个struct data
的数组,而count就是这样的结构。以下函数应该可以帮助您从用户空间中读取结构。下面的代码假设您在阅读时不会修改日志缓冲区或数组(这是一个简单的示例)。您可以修改以下内容以满足您的需求。确保同步数据结构(例如日志缓冲区)以确保您阅读的内容是什么。
是的!你可以使用全局声明结构并在seq_show中使用它。
static void *seq_start(struct seq_file *s, loff_t *pos)
{
if (*pos > count)
return NULL;
return pos;
}
static int seq_show(struct seq_file *s, void *v)
{
loff_t *pos = (loff_t *)v;
if (*pos == 0) {
seq_printk(s, "Address\t\t\tPID\tInfo\n");
}
seq_printk(s, "0x%p\t%u\t%u\n", drv_data[*pos].address, drv_data[*pos].pid,
drv_data[*pos].info);
return 0;
}
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
{
(*pos)++;
if (*pos >= count)
return NULL;
return pos;
}