Posted by: Catalin | October 2, 2008

Basic proc file system module

This is an example of proc file system basic usage regarding:

  • adding and removing a directory, or file under proc
  • handling I/O  of proc files

Having the proc_demo.ko module inserted into kernel, it will create /proc/{demo, demo/file} under you are able to perform simple I/O like:

  • echo “what ever you want” > /proc/demo/file
  • cat /proc/demo/file

Its purpose is to demonstrate the minimal usage of kernel proc API.

You should read Basic proc file system kernel API page first.

proc_demo.c

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


MODULE_LICENSE("GPL");

static char *file_content=NULL;
static struct   proc_dir_entry *proc_dir=NULL;
static struct   proc_dir_entry *proc_file=NULL;

ssize_t file_write(struct file *filp, const char __user *buff,
		   unsigned long len, void *data);

int file_read(char *page, char **start, off_t off,
		int count, int *eof, void *data);

ssize_t file_write( struct file *filp, const char __user *buff,unsigned long len, void *data)
{
    if (len>PAGE_SIZE) {
	printk(KERN_INFO "proc_demo module: file_write function len > PAGE_SIZE\n");
	return -ENOSPC;
    }

    if (copy_from_user(&file_content[0], buff, len))
	return -EFAULT;

    file_content[len]='\x0';
    printk(KERN_INFO "proc_demo module: you've written: %s\n",file_content);
    return len;
}

int  file_read( char *page, char **start, off_t off,int count, int *eof, void *data)
{
    return sprintf(page,"The user entered:\n%s\n",file_content),
	    strlen(page);
}

static int proc_demo_init(void) {

	int  ret=0;
	// We're alloc'ing memory for the file content buffer
	file_content=(char *)vmalloc(PAGE_SIZE);
	if (!file_content){
	    printk(KERN_INFO "proc_demo module: vmalloc: could not alocate memory\n");
	    goto demo_out;
	}

	memset(file_content, 0, PAGE_SIZE);

        // Creating the proc 'demo' directory
	proc_dir=proc_mkdir("demo", NULL);
        if (!proc_dir) {
	    printk(KERN_INFO "proc_demo module: demo directory creation failed\n");
            ret=-EAGAIN;
            goto proc_mkdir_failure;
	}

	/* creating 'file' and setting the read&&write function
	   handlers */
	proc_file=create_proc_entry("file",0600, proc_dir);
        if (proc_file) {
	    proc_file->read_proc  = file_read;
	    proc_file->write_proc = file_write;
	    proc_file->owner      = THIS_MODULE;
	}
	else {
    	    printk(KERN_INFO "proc_demo module: create_proc_entry: file\n");
	    ret= -EAGAIN;
	    goto proc_file_failure;
	}

	printk(KERN_INFO "proc_demo module: succesfully loaded\n");
        return ret;
proc_file_failure:
	remove_proc_entry("demo", NULL);
proc_mkdir_failure:
	vfree(file_content);
demo_out:
	printk(KERN_INFO "proc_demo module: not loaded loaded\n");
	return ret;
}

static void proc_demo_exit(void) {

        remove_proc_entry("file",proc_dir);
	remove_proc_entry("demo", NULL);

	if (file_content)
	    vfree(file_content);

	printk(KERN_INFO "proc_demo module: unloaded.\n");
}

module_init(proc_demo_init);
module_exit(proc_demo_exit);

Regarding a Makefile you can find a good example here.


Responses

  1. [...] you can find a good example at Basic proc file system module page. Possibly related posts: (automatically generated)Understanding proc file system in [...]


Leave a response

Your response:

Categories