Monday, October 3, 2011

Video RAM driver


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

#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/fs.h>

#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/device.h>
#include <linux/cdev.h>


#define VRAM_BASE 0x000A0000
#define VRAM_SIZE 0x00020000

static void __iomem *vram;
static dev_t first;
static struct cdev c_dev;
static struct class *cl;


static int my_open(struct inode *i, struct file *f)
{return 0;}

static int my_close(struct inode *i, struct file *f)
{return 0;}

static ssize_t my_read(struct file *f, char __user *buf,size_t len,loff_t *off)
{
    int i;
    unsigned char byte;

    if(*off >= VRAM_SIZE)
    {
         return 0;          
    }
   
    if(*off + len > VRAM_SIZE)
    {
        len = VRAM_SIZE - *off;
    }
   
    for(i=0; i
    {
        byte = ioread8((unsigned char *)vram + *off + i);
        if(copy_to_user(buf+i,&byte,1))
            return -EFAULT;
    }
    *off +=len;
    return len;
}

static ssize_t my_write(struct file *f,const char __user *buf, size_t len, loff_t *off)
{
    int i;
    unsigned char byte;

    if(*off >= VRAM_SIZE)
        return 0;

    if(*off + len > VRAM_SIZE)
        len = VRAM_SIZE - *off;

    for(i=0; i
    {
        if(copy_from_user(&byte,buf+i,1))
            return -EFAULT;
        iowrite8(byte,(unsigned char *)vram + *off +i);
    }
    *off += len;   
    return len;
}

static struct file_operations vram_fops =
{
    .owner = THIS_MODULE,
    .open = my_open,
    .release = my_close,
    .read = my_read,
    .write = my_write
};

static int __init vram_init(void)
{
    printk(KERN_INFO "VRAM init started...");
    if( (vram = ioremap(VRAM_BASE,VRAM_SIZE)) == NULL)
    {
        printk(KERN_ERR "Mapping video ram failed\n");
        return -1;
    }
    printk(KERN_INFO "Video RAM mapping OK");

    if(alloc_chrdev_region(&first,0,1,"vram") < 0)
        return -1;

    if( (cl = class_create(THIS_MODULE,"chrdrv")) == NULL)
    {
        unregister_chrdev_region(first,1);
        return -1;
    }       

    if(device_create(cl,NULL,first,NULL,"vram") == NULL)
    {
        class_destroy(cl);
        unregister_chrdev_region(first,1);
        return -1;
    }
   
    cdev_init(&c_dev,&vram_fops);
    if(cdev_add(&c_dev,first,1) == -1)
    {
        device_destroy(cl,first);
        class_destroy(cl);
        unregister_chrdev_region(first,1);
        return -1;
    }

    printk(KERN_INFO "Successful vram driver init...");
    return 0;
}

static void __exit vram_exit(void)
{
    cdev_del(&c_dev);
    device_destroy(cl,first);
    class_destroy(cl);
    unregister_chrdev_region(first,1);
    iounmap(vram);
    printk(KERN_INFO "Alvida: vram driver unregistered");
}

module_init(vram_init);
module_exit(vram_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("VINOD");
MODULE_DESCRIPTION("VRAM driver");

COMMANDS:

WRITE: echo -n "0123456789" > /dev/vram
READ: od -t x1 -v /dev/vram 


cat /proc/iomem
cat /proc/meminfo

No comments: