// file: chrdev.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h> // struct inode
#include <linux/cdev.h> // struct cdev
#include <asm/uaccess.h> // copy_from_user
//#include <linux/>
#define DEV_MAJOR_NUM 113
#define DEV_MINOR_NUM 8
#define DEV_NAME "GOD"
MODULE_LICENSE("Dual BSD/GPL");
static int z_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
struct z_dev
{
struct cdev cdev;
char *p_mem; // 没有用到
};
struct z_dev *s_p_dev = NULL;
struct file_operations s_fops =
{
.ioctl = z_ioctl, // ","
};
static int z_ioctl(struct inode * p_node, struct file *flp, unsigned int cmd, unsigned long param)
{
int buff[5] = {1,2,3,4,5};
copy_to_user((void*)param, buff, 5*sizeof(int));
return 0;
}
static int __init init(void)
{
struct z_dev *p_dev = NULL;
// dev_t register
dev_t dev_no = MKDEV(DEV_MAJOR_NUM, 0); // 次设备号不是0就失败?
if(register_chrdev_region(dev_no, 1, DEV_NAME)!=0)
{
printk("register_chrdev_region err\n");
}
// cdev register
p_dev = (struct z_dev *)kmalloc(sizeof(struct z_dev), 0);
if (p_dev==NULL)
{
printk("kmalloc err\n");
}
cdev_init(&p_dev->cdev, &s_fops);
p_dev->cdev.owner = THIS_MODULE;
p_dev->cdev.ops = &s_fops;
if (cdev_add(&p_dev->cdev, dev_no, 1)!=0)
{
printk("cdev_add err\n");
}
s_p_dev = p_dev;
return 0;
}
static void __exit exit(void)
{
dev_t dev_no = MKDEV(DEV_MAJOR_NUM, 0);
unregister_chrdev_region(dev_no, 1);
cdev_del(&s_p_dev->cdev);
if (s_p_dev!=NULL) kfree(s_p_dev);
return;
}
module_init(init);
module_exit(exit);
|