我正在努力更新我们的内核驱动程序,以便在Ubuntu 16.0.4上使用Linux内核4.4.0。驱动程序最后使用linux内核3.9.2。 在其中一个模块中,我们创建了一个procfs条目来读取/写入板载风扇监视值。风扇监控用于读/写CPU或GPU温度/调制等。值。
该模块使用以下api创建procfs条目:
struct proc_dir_entry *create_proc_entry(const char *name, umode_t
mode,struct proc_dir_entry *parent);
类似的东西:
struct proc_dir_entry * proc_entry =
create_proc_entry("fmon_gpu_temp",0644,proc_dir);
proc_entry->read_proc = read_proc;
proc_entry->write_proc = write_proc;
现在,read_proc以这种方式实现:
static int read_value(char *buf, char **start, off_t offset, int count, int *eof, void *data) {
int len = 0;
int idx = (int)data;
if(idx == TEMP_FANCTL)
len = sprintf (buf, "%d.%02d\n", fmon_readings[idx] / TEMP_SAMPLES,
fmon_readings[idx] % TEMP_SAMPLES * 100 / TEMP_SAMPLES);
else if(idx == TEMP_CPU) {
int i;
len = sprintf (buf, "%d", fmon_readings[idx]);
for( i=0; i < FCTL_MAX_CPUS && fmon_cpu_temps[i]; i++ ) {
len += sprintf (buf+len, " CPU%d=%d",i,fmon_cpu_temps[i]);
}
len += sprintf (buf+len, "\n");
}
else if(idx >= 0 && idx < READINGS_MAX)
len = sprintf (buf, "%d\n", fmon_readings[idx]);
*eof = 1;
return len;
}
此读取功能肯定假定用户已提供足够的缓冲空间来存储温度值。这在用户空间程序中正确处理。此外,对于对此函数的每次调用,读取值都是完整的,因此对于相同温度值的后续读取不存在支持/需要。 另外,如果我使用&#34; cat&#34;来自shell的这个procfs条目的程序,&#39; cat&#39;程序正确显示值。我认为,这可以通过将EOF设置为true并返回读取字节数来支持。
新的Linux内核不再支持此API。
我的问题是:
如何将此API更改为新的procfs API结构,保持功能相同:每次读取都应返回值,程序&#39; cat&#39;也应该工作正常而不是进入无限循环?
答案 0 :(得分:1)
Linux上读取文件的主要用户界面为http://twig.sensiolabs.org/doc/tags/macro.html。它在内核空间中的对是{em> struct file_operations 中的.read
函数。
内核空间中读取文件的所有其他机制( read_proc , seq_file 等)实际上是{的参数化)实现{ {1}}功能。
内核将EOF指示符返回给用户空间的唯一方法是返回0作为读取的字节数。
对3.9内核实现的.read
实现实际上将read_proc
标志实现为在下次调用时返回0。并且eof
实际执行了cat
的第二次调用以查找该文件已结束。
(此外,read
执行两次以上的读取调用:首先执行计数,其次是计数等等页面大小减1,最后一个剩余计数。)
“一次性”读取实现的最简单方法是在cat
模式下使用 seq_file 。