打印

关于/proc文件系统及seq_file实现,求解惑!!

关于/proc文件系统及seq_file实现,求解惑!!

第一:/proc文件系统是什么 ?这个网上很多,说的很细,我也就不说了。但是他是做什么用的,网上也很多,但是我不解,就我目前了解的,简单的说,/proc是驱动程序的一种调式方法(如有不对可以指出),那么怎样让我的/proc文件系统与我的驱动程序建立联系!!??如下面最简单的一个/proc文件系统例子:
复制内容到剪贴板
代码:
// include kernel head files
#include <linux/init.h>
#include <linux/module.h>

#include <linux/proc_fs.h>
#include <asm/uaccess.h>

// licensed under BSD/GPL
MODULE_LICENSE("Dual BSD/GPL");

static struct proc_dir_entry *prwd_dir = NULL;
static struct proc_dir_entry *prwd_rdonly = NULL;
static struct proc_dir_entry *prwd_rdwr = NULL;

static char sbufr[ 100 ] = "One test string from reading only !\n";
static char sbufrw[ 1000 ] = "";

// read-only function
static int prwd_rdonly_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
        sprintf( page, "%s", sbufr );

        *eof = 1;

        return strlen( sbufr );
}

// read function for read-write
static int prwd_rdwr_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
        int len;

        len = strlen( sbufrw );
        if( len <= off ) {
                printk(KERN_ALERT "File pointer at end of file or no data for reading in read-write buffer !\n");
                return -EINVAL;
        }

        if( ( len - off ) < count ) {
                count = len - off;
        }

        memcpy( page, ( sbufrw + off ), count );

        if( len <= ( off + count ) ) {
                *eof = 1;
        }

        return count;
}

// write function for read-write
static int prwd_rdwr_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
        unsigned long cnt = count;

        if( cnt >= sizeof( sbufrw ) ) {
                cnt = sizeof( sbufrw ) - 1;
        }

        if( copy_from_user( sbufrw, buffer, cnt ) ) {
                printk(KERN_ALERT "Failure to copy data from user space !\n");
                return -EFAULT;
        }

        sbufrw[ cnt ] = '\0';

        return cnt;
}

// initialize module function
static int __init procreadwritedemo_init(void)
{
        printk(KERN_ALERT "Entry procreadwritedemo_init !\n");

        // create directory: procreadwritedemo in /proc
        prwd_dir = proc_mkdir( "procreadwritedemo", NULL );
        if( NULL == prwd_dir ) {
                printk(KERN_ALERT "Cann't create directory: /proc/procreadwritedemo !\n");
                goto failure_create_dir;
        }
        printk(KERN_ALERT "Success to create directory: /proc/procreadwritedemo !\n");

        // create read-only file: rdonly in /proc/procreadwritedemo
        prwd_rdonly = create_proc_read_entry( "rdonly", 0400, prwd_dir, prwd_rdonly_read, NULL );
        if( NULL == prwd_rdonly ) {
                printk(KERN_ALERT "Cann't create read-only file: /proc/procreadwritedemo/rdonly !\n");
                goto failure_create_rdonly;
        }
        printk(KERN_ALERT "Success to create read-only file: /proc/procreadwritedemo/rdonly !\n");

        // create read-write file: rdwr in /proc/procreadwritedemo
        prwd_rdwr = create_proc_entry( "rdwr", 0666, prwd_dir );
        if( NULL == prwd_rdwr ) {
                printk(KERN_ALERT "Cann't create read-write file: /proc/procreadwritedemo/rdwr !\n");
                goto failure_create_rdwr;
        }
        prwd_rdwr->read_proc = prwd_rdwr_read;
        prwd_rdwr->write_proc = prwd_rdwr_write;
        printk(KERN_ALERT "Success to create read-write file: /proc/procreadwritedemo/rdwr !\n");

        return 0;

failure_create_rdwr:
        remove_proc_entry( "rdonly", prwd_dir );
failure_create_rdonly:
        remove_proc_entry( "procreadwritedemo", NULL );
failure_create_dir:
        return -EFAULT;
}

// clean up module function
static void __exit procreadwritedemo_exit(void)
{
        printk(KERN_ALERT "Entry procreadwritedemo_exit !\n");

        // remove files and directory created in /proc
        remove_proc_entry( "rdwr", prwd_dir );
        remove_proc_entry( "rdonly", prwd_dir );
        remove_proc_entry( "procreadwritedemo", NULL );
}

// the declarations of initilization and cleaning up module funcitons
module_init( procreadwritedemo_init );
module_exit( procreadwritedemo_exit );

// module information
MODULE_AUTHOR("wensheng");
MODULE_DESCRIPTION("Proc filesystem read/write demo");
MODULE_VERSION("0.0.1");
MODULE_ALIAS("ProcReadWriteDemo");
上面的一例,完全是一个独立/proc系统代码的实现,问题是:他是那怎与我想调试的驱动(如一个块设备)程序建立关系了,如是不能跟我的相关驱动建联系,那/proc文件系统存在意义是什么 (简单说就是做什么用的,最好可以举个易懂的例子)??


第二:关于seq_file机制
有如下代码
复制内容到剪贴板
代码:
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
struct proc_dir_entry proc_root;

void * our_seq_start(struct seq_file *m, loff_t *pos)
{
//printk("<0>""in our_seq_start/n");
if(*pos == 0)
  return pos;
return NULL;
}

void * our_seq_stop(struct seq_file *m, void *v)
{
//printk("/nDO NOTHING/n");
}


int our_seq_show(struct seq_file *m, loff_t *pos)
{
static unsigned long counter = 0;
int i;
for(i=0;i<10;i++)
seq_printf(m,"the counter is %d/n",i);
return 0;
}

void *our_seq_next(struct seq_file *m, loff_t *pos)
{
static unsigned long counter_next = 0;
if(pos < 1)
{
  counter_next++;
  pos++;
  return pos;
}
else
{
  *pos = 0;
  return NULL;
}
}

static const struct seq_operations our_seq_ops = {
.start = our_seq_start,
.next  = our_seq_next,
.stop  = our_seq_stop,
.show  = our_seq_show
};

static int our_seq_open(struct inode *inode, struct file *filp)
{
printk("<0>""in our_seq_open/n");
return seq_open(filp, &our_seq_ops);
}
int our_ioctl()
{
printk("<0>""in our_seq_ioctl/n");
return 0;
}

int our_write()
{
printk("<0>""in our_seq_write/n");
return 5;
}
struct file_operations our_proc_ops = {
.open    = our_seq_open,
.read    = seq_read,
.write   = our_write,
.llseek  = seq_lseek,
.ioctl   = our_ioctl,
.release = seq_release
};

int our_init()
{
proc_create("hehe", 0, NULL, &our_proc_ops);
return 0;
}
void our_exit()
{
remove_proc_entry("hehe",NULL);
}
module_init(our_init);
module_exit(our_exit);
上面代码是目前我在网上查到的/proc文件系统实现中唯一个涉及到ioctl操作(此处不关心代码是否有错,关心功能码是否以实现),因为之前所有相关seq_file机制建立/proc,中struct file_operations,只有如下操作
复制内容到剪贴板
代码:
struct file_operations our_proc_ops = {
.open    = our_seq_open,
.read    = seq_read,
.llseek  = seq_lseek,
.release = seq_release
};
而且我们只用实现open(),而read,lseek,release,都是seq_file内部实现,我们可不管。问题是没有write(),没有ioctl()(为什么没有,我们可以暂不讨论),我想问的是,我们可否像上面那个代码一样添加自己的write与ioctl功能。
      以上都是自己跟据现有资做出的理解,如有不对,请您不吝指出,还有我的一些不解之处,求大神解惑!!

TOP