实现一个基本框架
#define notice(fmt,args...) printk(KERN_NOTICE "scull-->" fmt,##args) #define error(fmt,args...) printk(KERN_ERR "scull-->" fmt,##args) static __init int scull_init(void) { notice("scull init\n"); return 0; } static __exit void scull_exit(void) { notice("scull exit\n"); } module_init(scull_init); module_exit(scull_exit); MODULE_AUTHOR("xxxxxx"); MODULE_DESCRIPTION("Share Buffer"); MODULE_ALIAS("scull"); MODULE_VERSION("V1.0");
分配设备号注册字符设备
int register_chrdev_region(dev_t,unsigned int,const char*);表示静态的申请和注册设备号
int alloc_chrdev_region(dev_t,unsigned int,const char*);表示动态的申请和注册设备号
int register_chrdev(unsigned int,const char*,struct file_operations*);表示int为0时动态注册,非零静态注册
dev_t dev_num=MKDEV(major_no,0);将设备号转换为dev_t类型变量,第一个参数是主设备号,第二个是次设备号
为设备分配内存此时,使用lsmod,可以发现你的设备就在其中
1.静态内存初始化
2.动态内存初始化struct cdev my_cdev;
cdev_init(&my_cdev, &fops);//设备操作结构体
my_cdev.owner = THIS_MODULE;
添加设备到系统struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &fops;
my_cdev->owner = THIS_MODULE;
从系统去除一个字符设备int cdev_add(struct cdev *p, dev_t num, unsigned count);num 是这个设备响应的第一个设备号, count 是关联到设
备的设备号的数目. 常常是 1
void cdev_del(struct cdev *dev);
释放设备号
实例void unregister_chrdev_region(dev_t first, unsigned int count);
#define notice(fmt,args...) printk(KERN_NOTICE "scull-->" fmt,##args) #define error(fmt,args...) printk(KERN_ERR "scull-->" fmt,##args) #define DEV_NAME "scull" struct scull_dev { struct cdev cdev; }; static struct file_operations fops = { .owner = THIS_MODULE, }; static int major = 0; static int setup_scull(struct scull_dev *p_dev) { int ret; cdev_init(&(p_dev->cdev), &fops); p_dev->cdev.owner = THIS_MODULE; ret = cdev_add(&p_dev->cdev, MKDEV(major,0), 1); if (ret) { error("cdev_add err\n"); return -1; } return 0; } static __init int scull_init(void) { int ret = 0; dev_t dev_num = MKDEV(major,0);//将设备号转成dev_t类型 if (major) { ret = register_chrdev_region(dev_num, 1, DEV_NAME);//知道设备号,使用静态分配 } else { ret = alloc_chrdev_region(&dev_num, 0, 1, DEV_NAME);//不知道知道设备号,使用动态分配 major = MAJOR(dev_num);//通过dev_t类型获取主设备号 } struct scull_dev *pscull_dev = kmalloc(sizeof(struct scull_dev),GFP_KERNEL); if (NULL == pscull_dev) { error("kmalloc err\n"); goto err_kmalloc; } ret = setup_scull(pscull_dev); if (ret < 0) { return -1; } notice("scull init\n"); return 0; err_kmalloc: unregister_chrdev_region(MKDEV(major,0), 1); return -1; } static __exit void scull_exit(void) { unregister_chrdev_region(MKDEV(major,0), 1); notice("scull exit\n"); } module_init(scull_init); module_exit(scull_exit); MODULE_AUTHOR("xxxxxx"); MODULE_DESCRIPTION("Share Buffer"); MODULE_ALIAS("scull"); MODULE_VERSION("V1.0");