字符设备驱动——globalmem(宋宝华第6章)

一、模块加载与卸载

1.在模块的加载中要实现设备号的申请与cdev的注册。
先用int register_chrdev_region(dev_t from, unsigned count, const char *name)或者int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)申请设备号。
在第一个函数register_chrdev_region中from是指希望申请的设备号,count是希望申请的设备号的数目,name是设备名。
在第二个函数alloc_chrdev_region中,是动态申请设备号,即自动分配系统空闲的设备号。dev是设备号地址,baseminor是申请的设备的第一个次设备号,count是希望申请的设备号的数目,name是设备名。

内核中有cdev结构体,描述一个字符设备。结构体定义如下

struct cdev {
	struct kobject kobj;
	struct module *owner;
	const struct file_operations *ops;
	struct list_head list;
	dev_t dev;
	unsigned int count;
};

习惯上,工程师为设备定义一个设备相关的结构体(包含设备涉及的cdev和私有数据和信号量)

struct xxx_dev_t {
	struct cdev cdev;
	. . . 
}xxx_dev;

然后用初始化函数void cdev_init(struct cdev *cdev, const struct file_operations *fops)来初始化cdev的成员。
cdev的注册是通过 int cdev_add(struct cdev *, dev_t, unsigned)向系统添加一个cdev。

2.模块的卸载要实现设备号的释放和cdev的注销
若在模块加载函数中申请了设备结构体内存则要释放设备结构体内存。
void cdev_del(struct cdev *)用来注销cdev。
void unregister_chrdev_region(dev_t from, unsigned count)用来释放设备号。
加载和卸载设备驱动源代码如下:

/* 初始化并注册cdev */
static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
{
	int err, devno = MKDEV(globalmem_major, index);

	cdev_init(&dev->cdev, &globalmem_fops);
	dev->cdev.owner = THIS_MODULE;
	err = cdev_add(&dev->cdev, devno, 1);
	if (err)
		printk(KERN_NOTICE "Error %d adding globalmem %d", err, index);
}

/* 设备驱动模块加载函数 */
int globalmem_init(void)
{
	int result;
	dev_t devno = MKDEV(globalmem_major, 0);   /*   devno = (250<<20) | 0   */

	/* 申请设
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值