2018年2月13日 星期二

Linux kernel - 建立讀寫屬性的proc entry

#include <linux/module.h>
#include <linux/init.h>

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

MODULE_LICENSE("Dual BSD/GPL");

#define PROCNAME "sample"

static int sample_flag = 0;

static int sample_proc_read(char *buf, char **start, off_t offset,
    int count, int *eof, void *data)
{
 int len = 0;

#if 0
 printk(KERN_INFO "buf=%p, *start=%p, offset=%d, count=%d, *eof=%d, data=%p\n",
   buf, *start, (int)offset, count, *eof, data);
#endif

 len += sprintf(buf + len, "%d\n", sample_flag);

 if (len > PAGE_SIZE)
  return -ENOBUFS;

 return len;
}

static int sample_proc_write(struct file *file, const char *buffer,
   unsigned long count, void  *data)
{
 char buf[16];
 unsigned long len = count;
 int n;

 printk(KERN_INFO "len = %d\n", (int)len);

 if (len >= sizeof(buf))
  len = sizeof(buf) - 1;

 /* asm/uacacess.h */
 if (copy_from_user(buf, buffer, len))
  return -EFAULT;
 buf[len] = '\0';

 n = simple_strtol(buf, NULL, 10);

 if (n == 0)
  sample_flag = 0;
 else
  sample_flag = 1;

 return (len);
}

static int sample_init(void)
{
 struct proc_dir_entry *entry;

 entry = create_proc_entry(PROCNAME, 0666, NULL);

 if (entry == NULL) {
  printk(KERN_WARNING "proc: unable to create proc entry\n");
  return -ENOMEM;
 }

 entry->read_proc = sample_proc_read;
 entry->write_proc = sample_proc_write;

 printk(KERN_INFO "driver loaded\n");

 return 0;
}

static void sample_exit(void)
{
 remove_proc_entry(PROCNAME, NULL);

 printk(KERN_INFO "driver unloaded\n");
}

module_init(sample_init);
module_exit(sample_exit);

沒有留言:

張貼留言