|
楼主 |
发表于 2008-10-4 23:49:38
|
显示全部楼层
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>
#define VIRTUAL_CHAR_MAJOR 240
#define VIRTUAL_CHAR_DEVICE_NAME "VirtualCharDevice"
static int virtual_char_open(struct inode *inode, struct file *file)
{
printk(KERN_EMERG"+++++++++++++++++++++\n");
printk(KERN_EMERG"virtual_char:device open\n");
printk(KERN_EMERG"pid=%d,comm=%s\n",current->pid,current->comm);
printk("device <%d,%d>\n",MAJOR(inode->i_rdev),MINOR(inode->i_rdev));
(file->private_data) = (void *)0x76543210;
return 0;
}
static int virtual_char_close(struct inode *inode, struct file *file)
{
printk(KERN_EMERG"virtual_char:device close\n");
printk(KERN_EMERG"----------------------\n");
return 0;
}
static ssize_t virtual_char_read(struct file *file, char *buf, size_t count, loff_t *offset)
{
printk(KERN_EMERG"virtual_char:device read=%d\n",count);
if(count >= sizeof(unsigned int)){
if(copy_to_user((void __user *)buf,(void *)(&file->private_data),sizeof(unsigned int)))
return -EFAULT;
}
return count;
}
static ssize_t virtual_char_write(struct file *file, const char *buf, size_t count, loff_t *offset)
{
printk(KERN_EMERG"virtual_char:device write=%d\n",count);
return count;
}
static loff_t virtual_char_llseek(struct file *file,loff_t offset,int whence)
{
printk(KERN_EMERG"virtual_char:device llseek: offset=%x whence=%x\n",(unsigned int)offset,whence);
return 0;
}
static int virtual_char_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
char argk[4];
argk[0] = 0;
argk[1] = 1;
argk[2] = 2;
argk[3] = 3;
printk(KERN_EMERG"virtual_char:device ioctl=%x\n",cmd);
switch(cmd)
{
case 0:
printk(KERN_EMERG"ctl NO.0\n");
if(copy_from_user(argk,(void __user *)arg,4))
return -EFAULT;
printk("arg=%x,%x,%x,%x\n",argk[0],argk[1],argk[2],argk[3]);
break;
case 1:
printk(KERN_EMERG"ctl NO.1\n");
if(copy_to_user((void __user *)arg,argk,4))
return -EFAULT;
break;
default:
break;
}
return 0;
}
static struct file_operations virtual_char_fops = {
.llseek = virtual_char_llseek,
.read = virtual_char_read,
.write = virtual_char_write,
.ioctl = virtual_char_ioctl,
.open = virtual_char_open,
.release = virtual_char_close,
};
static int virtual_char_init(void)
{
int res;
printk(KERN_EMERG"virtual_char register\n");
res = register_chrdev(VIRTUAL_CHAR_MAJOR, VIRTUAL_CHAR_DEVICE_NAME, &virtual_char_fops);
if (res < 0) {
printk(KERN_EMERG"virtual_char register fails\n");
return res;
}
// set_current_state(TASK_INTERRUPTIBLE);
// schedule_timeout(4000);
// mdelay(4000);
return 0;
}
static void virtual_char_cleanup(void)
{
printk(KERN_EMERG"virtual_char unregister\n");
unregister_chrdev(VIRTUAL_CHAR_MAJOR, VIRTUAL_CHAR_DEVICE_NAME);
return;
}
module_init(virtual_char_init);
module_exit(virtual_char_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HanChao");
//gcc -O2 -D__KERNEL__ -DMODULE -I/usr/include/ -c virtual_char.c -o m.ko |
|