2018年2月13日 星期二

Linux kernel - 建立proc entry的資料夾

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

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

MODULE_LICENSE("Dual BSD/GPL");

#define PROCDIR "mydir"
#define PROCSYMLINK "myuptime"
#define PROCNAME "timer"
static unsigned int timer1 = 1000;
static struct proc_dir_entry *dir_entry;
static struct proc_dir_entry *symlink_entry;

static int sample_proc_read(char *buf, char **start, off_t offset,
    int count, int *eof, void *data)
{
    char *p = buf;
    p += sprintf(p, "timer1 = %d (ms)\n", timer1);
    *eof = 1;
 
    if ((p - buf) > PAGE_SIZE)
        return -ENOBUFS;

    return p - buf;
}

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

    if (count > sizeof(buf))
        return -EINVAL;
    if (copy_from_user(buf, buffer, count))
        return -EFAULT;

    while (*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++;
        timer1 = simple_strtoul(ptr, &ptr, 10);

    return count;
}

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

    dir_entry = proc_mkdir(PROCDIR, NULL);

    if (dir_entry) {

        entry = create_proc_entry(PROCNAME, 0666, dir_entry);

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

        entry->read_proc = (read_proc_t *) sample_proc_read;
        entry->write_proc = (write_proc_t *) sample_proc_write;

         symlink_entry = proc_symlink(PROCSYMLINK, dir_entry, "../uptime");
  
        if (symlink_entry == NULL) {
            printk(KERN_WARNING "sample: unable to create symlink proc entry\n");
            return -ENOMEM;
        }
    }

    return 0;
}

static void sample_exit_proc(void)
{
    if (dir_entry) {
        remove_proc_entry(PROCNAME, dir_entry);
        remove_proc_entry(PROCSYMLINK, dir_entry);
        remove_proc_entry(PROCDIR, NULL);

        dir_entry = NULL;
    }
}

static int __init sample_init(void)
{
    sample_init_proc();

    printk(KERN_INFO "driver loaded\n");

    return 0;
}

static void __exit sample_exit(void)
{
    int ret = 0;
    sample_exit_proc();

    printk(KERN_INFO "driver unloaded (%d)\n", ret);
}

module_init(sample_init);
module_exit(sample_exit);

沒有留言:

張貼留言