網頁

2009年6月8日 星期一

Linux 2.6 Driver Template


#include <linux/module.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/io.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>

typedef struct
{
void **data;
struct cdev *cdev ;

}DBG_Dev_Tag;

#define DBG_MAJOR 111
#define DBG_MINOR 1
#define MAXDEVICENUM 1

#define DEBUG_IOC_MAGIC 'D'
#define DEBUG_IOCSHOWDEB _IOR(DEBUG_IOC_MAGIC, 1, int)

DBG_Dev_Tag *DBG_devices;


int dbg_major = DBG_MAJOR;
int dbg_minor;

static struct file_operations DBG_fops =
{
.ioctl = DBG_ioctl,
.read = DBG_read,
.write = DBG_write,
.open = DBG_open,
.release = DBG_release,
};

int DBG_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
struct net_device *dev = &_wpcm450_netdevice;

switch (cmd)
{
case DEBUG_IOCSHOWDEB:
//show something

break;
default:
break;
}

return 0;
}

ssize_t DBG_read (struct file *filp, char *buf, size_t count, loff_t *offset)
{
return 0;
}

ssize_t DBG_write (struct file *file, const char *buf, size_t count, loff_t *offset)
{
return 0;
}

static int DBG_open(struct inode *inode, struct file *filp)
{
DBG_Dev_Tag *dev;

dev = container_of (inode->i_cdev,DBG_Dev_Tag,cdev);

filp-> private_data = dev;

return 0;
}

static int DBG_release(struct inode *inode, struct file *filp)
{


return 0;
}



static void dbg_setup_cdev(DBG_Dev_Tag *dev,int index)
{
int err;
int dev_id = MKDEV(dbg_major,dbg_minor + index );

cdev_init(dev->cdev,&DBG_fops);

dev->cdev->owner = THIS_MODULE;

dev->cdev->ops = &DBG_fops;

err = cdev_add(dev->cdev,dev_id,1);

if (err)
printk ("error %x adding dbg%x\n",err,index);

}


static int __init DBG_init(void)
{
int result;
dev_t dev_id;


DBG_devices = kmalloc (sizeof (DBG_Dev_Tag) * MAXDEVICENUM ,GFP_KERNEL);

if (DBG_devices == NULL)
{
result = -ENOMEM;
return result;
}

memset(DBG_devices, 0, MAXDEVICENUM * sizeof(DBG_Dev_Tag));

if (dbg_major)
{
dev_id = MKDEV(dbg_major,dbg_minor);

result = register_chrdev_region(dev_id, 1, "debug");
}
else
{
result = alloc_chrdev_region(&dev_id,DBG_MINOR,1,"dbg");
dbg_major = MAJOR(dev_id);
}

if (result < 0 )
{
printk ("can't get major %d\n",dbg_major);
return result;
}

DBG_devices->cdev = cdev_alloc();

dbg_setup_cdev(DBG_devices,1);

return 0;
}

static void __exit DBG_exit(void)
{
dev_t dev_id;

kfree(DBG_devices);

cdev_del(DBG_devices ->cdev);

dev_id = MKDEV(dbg_major,dbg_minor);
unregister_chrdev_region(dev_id,1);
return;
}

MODULE_AUTHOR("XXXXXXXXXX");
MODULE_DESCRIPTION("Debug driver");
MODULE_LICENSE("GPL");

module_init(DBG_init);
module_exit(DBG_exit);

//**************************Makefile *******************************
KERNELDIR =   obj-m := test_drv.o
#combine two drivers into the one. 
#test_drv-objs := testA_drv.o testB_drv.o  
ifneq ($(KERNELRELEASE),)  
CFLAGS +=  -D__KERNEL__ -DMODULE  -Wall -DEXPORT_SYMTAB -O2  
else  
all:  
 $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules endif 

沒有留言:

張貼留言