我试图理解procfs的seq文件接口。我创建了一个小内核模块来读取/写入proc条目。我写的模块是:
#define PROC_DIR_NAME "driver/kernel_test_dir2"
#define KERNEL_DATA "This is kernel test"
static struct proc_dir_entry *proc_entry_file = 0;
static struct proc_dir_entry *proc_dir = 0;
#define PROC_ENTRY_BUFFER_SIZE 64
struct proc_entry
{
ssize_t buffer_length;
char buffer[PROC_ENTRY_BUFFER_SIZE];
};
static int proc_entry_seq_show(struct seq_file *s, void *v)
{
printk(KERN_INFO "kernel_test:proc_entry_seq_show\n");
struct proc_entry* kmem = s->private;
if(kmem)
{
printk(KERN_INFO "kernel_test:proc_entry_seq_show:s->private=%x\n",s->private);
seq_printf(s, "%s\n",&(kmem->buffer[0]));
}
return 0;
}
static int proc_entry_open(struct inode *inode, struct file *file)
{
struct proc_entry* kmem = kmalloc(sizeof(struct proc_entry),GFP_KERNEL);
return single_open(file,&proc_entry_seq_show,(void*)kmem);
};
static int proc_entry_close(struct inode *inode, struct file *file)
{
struct seq_file *s = file->private_data;
struct proc_entry* kmem = (struct proc_entry*)(s->private);
kfree(kmem);
return single_release(inode,file);
};
static ssize_t proc_entry_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
ssize_t len=0;
loff_t pos;
struct seq_file* seqfile = (struct seq_file*)(file->private_data);
printk(KERN_INFO "kernel_test:proc_entry_write\n");
printk(KERN_INFO "kernel_test:proc_entry_write:offset = %d, count=%d\n",*ppos,count);
if(seqfile)
{
printk(KERN_INFO "kernel_test:proc_entry_write:seqfile\n");
struct proc_entry* kmem = (struct proc_entry*)(seqfile->private);
if(kmem)
{
printk(KERN_INFO "kernel_test:proc_entry_write:kmem\n");
pos = *ppos;
if(pos<0)
return -EINVAL;
if(count > PROC_ENTRY_BUFFER_SIZE)
count = PROC_ENTRY_BUFFER_SIZE;
if(copy_from_user(&(kmem->buffer[0]), buf, count))
return -EFAULT;
(*ppos) = pos + count;
kmem->buffer_length = count;
return count;
}
printk(KERN_INFO "kernel_test:proc_entry_write:kmem does not exist!\n");
}
printk(KERN_INFO "kernel_test:proc_entry_write:seqfile does not exist!\n");
return -EFAULT;
}
static struct file_operations fops_proc_entry = {
.open = proc_entry_open,
.read = seq_read,
.release = proc_entry_close,
.write = proc_entry_write,
};
static int __init init_test_kernel(void) {
int rv;
proc_dir = proc_mkdir(PROC_DIR_NAME, NULL);
if(proc_dir == NULL) {
rv = -ENOMEM;
}
proc_entry_file = proc_create ("kernel_test_file", S_IRUSR | S_IWUSR, proc_dir,&fops_proc_entry);
if(!proc_entry_file) {
rv = -ENOMEM;
}
printk(KERN_INFO "kernel_test: Kernel Test module started\n");
return 0;
}
// Cleanup module
static void __exit cleanup_test_kernel(void) {
remove_proc_entry("kernel_test_file", proc_dir);
remove_proc_entry(PROC_DIR_NAME,NULL);
printk(KERN_INFO "kernel_test: Kernel Test module stopped\n");
}
module_init(init_test_kernel);
module_exit(cleanup_test_kernel);
我写了一个小程序来测试我的内核模块,示例程序的源代码是:
#define BUFFER_DATA "This is test kernel data by me"
#define MAX_BUFFER_SIZE 64
static char write_buffer[MAX_BUFFER_SIZE];
static char read_buffer[MAX_BUFFER_SIZE];
int main()
{
int fd;
int count=0;
fd = open("/proc/driver/kernel_test_dir2/kernel_test_file",O_RDWR);
if(fd<0)
{
std::cout <<"Could not open file /proc/driver/kernel_test_dir2/kernel_test_file !"<<
strerror(errno)<<std::endl;
return -1;
}
sprintf(write_buffer,"%s",BUFFER_DATA);
std::cout << "Write Buffer to be written is - "<<write_buffer<<std::endl;
count = write(fd,write_buffer,strlen(write_buffer));
std::cout << "The bytes requested to be written are - "<<strlen(write_buffer) <<std::endl;
if(count<0)
{
std::cout<<"write error : " << strerror(errno)<<std::endl;
return -1;
}
else if(count!=strlen(write_buffer))
{
std::cout<<"Wrote only "<<count<<" bytes, but was asked to write "<<strlen(write_buffer)<<" bytes"<<std::endl;
return -1;
}
count = read(fd,read_buffer,MAX_BUFFER_SIZE);
if(count < 0)
{
std::cout<<"read error : " << strerror(errno)<<std::endl;
return -1;
}
std::cout << "buffer read as - "<<read_buffer<<std::endl;
close(fd);
return 0;
}
我面临的问题是写模块的调用会以某种方式设置&#39;计数&#39; &#34; proc_entry_write()&#34;中的字节数为0(零)。
我的示例应用程序执行的系统日志消息是:
Jun 20 16:03:51 kernel: [356787.943092] kernel_test:proc_entry_write
Jun 20 16:03:51 kernel: [356787.943554] kernel_test:proc_entry_write:offset = 0, count=0
Jun 20 16:03:51 kernel: [356787.943944] kernel_test:proc_entry_write:seqfile
Jun 20 16:03:51 kernel: [356787.944344] kernel_test:proc_entry_write:kmem
Jun 20 16:03:51 kernel: [356787.944978] kernel_test:proc_entry_seq_show
Jun 20 16:03:51 kernel: [356787.945408] kernel_test:proc_entry_seq_show:s->private=ee600600