Friday, 12 September 2014

Procfs tutorial



Sample code for creating entries inside proc filesystem:

=======================================================================
/*
 * This Kernel module will create 3 proc entry, one parent directory and two
 * entries under this parent.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

#define MODULE_NAME "Proc_entry_sample_module"
#define MAX_BUFFER_SIZE 1024
#define PROC_DIR_NAME "Hello_proc_dir"

static char procfs_buffer[MAX_BUFFER_SIZE];
static unsigned long procfs_buffer_size = 0;
static struct proc_dir_entry *dir , *file1 , *file2;


int hello_file_read (char *buffer, char ** buffer_location, off_t offset ,
                        int buffer_length ,int *eof ,  void *data )
{
int ret;
printk(KERN_INFO"\nReading /Procfs..");

if (offset > 0) {
ret = 0;
                *eof = 1;
} else {
memcpy (buffer,procfs_buffer,procfs_buffer_size);
ret=procfs_buffer_size;
}
printk (KERN_INFO"\nret = %d",ret);
return ret;
}

int hello_file_write(struct file *file , const char *buffer,
                                unsigned long count,void *data )
{
printk (KERN_INFO"\nWriting to /ProcFS..");
        printk("count=%d",count);
procfs_buffer_size = count;
if (procfs_buffer_size > MAX_BUFFER_SIZE) {
procfs_buffer_size = MAX_BUFFER_SIZE;
} else {
                procfs_buffer_size = count;
        }
if (copy_from_user (procfs_buffer,buffer,procfs_buffer_size))
return -EFAULT;
printk (KERN_INFO"\nret = %lu",procfs_buffer_size);
return procfs_buffer_size;
}

static int __init my_init_function(void)
{
int ret = 0;
dir = proc_mkdir (PROC_DIR_NAME,NULL);
if(dir == NULL) {
ret = -ENOMEM;
printk (KERN_ERR"\nDirectory creation failed");
                goto out_err;
        } else {
printk (KERN_INFO"\nDirectory created");
}

file1 = create_proc_entry ("file1",0644,dir);
if (file1 == NULL) {
ret = -ENOMEM;
printk ("\nfile1 creation failed");
                goto out_err;
} else {
printk(KERN_INFO"\nfile1 under dir created");
}

file1->read_proc=hello_file_read;
file1->write_proc=hello_file_write;
file1->mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

file2 = create_proc_entry ("file2",0644,dir);
        if (file2 == NULL) {
ret = -ENOMEM;
printk ("\nfile2 creation failed");
                goto out_err;
} else {
printk(KERN_INFO"\nfile2 under dir created");
}

file2->read_proc=hello_file_read;
        file2->write_proc=hello_file_write;
file2->mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;


out:
return ret;
out_err:
        printk("\nModule failed to create proc entries !!");
        goto out;

}

static void __exit my_exit_function(void)
{
remove_proc_entry("file1",dir);
remove_proc_entry("file2",dir);
remove_proc_entry("dir",NULL);
printk(KERN_INFO"\nAll Proc entries of %s kernel module removed"
                                ,MODULE_NAME);
printk(KERN_INFO"\n%s module unregistered",MODULE_NAME);

}

module_init(my_init_function);
module_exit(my_exit_function);

MODULE_DESCRIPTION("Kernel module for handing procfs entires.");
MODULE_AUTHOR("Narendra Pal Singh");
MODULE_LICENSE("GPL");

========================================================================

Makefile:

obj-m += proc_example.o 

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

========================================================================

Steps to run:

1.  #make
2.  #insmod proc_example.ko
3.  #cd /proc

You will a directory of name "Hello_proc_dir".

4. #cd Hello_proc_dir
now can you can fire echo / cat commands to these two proc files named "file1" and "file2"

No comments:

Post a Comment