Linux设备驱动程序学习笔记03:字符设备驱动程序I

在Linux内核中用cdev结构体来表示一个字符设备,cdev的定义在linux/Cdev.h中:

struct cdev {
	struct kobject kobj; //内嵌的kobject
	struct module *owner; //指向实现驱动程序的模块(如果有的话)
	const struct file_operations *ops; //指向驱动程序的文件操作表
	struct list_head list; //与字符设备对应的设备文件的链表头
	dev_t dev; //驱动的设备号
	unsigned int count;  //设备号的范围
};

该结构体的dev成员定义了设备号。Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。使用ll命令查看/dev目录下的内容,可看到同下面类型的输出:


其中tty是设备名称。5, 0 分别是主设备号和次设备号。主设备号标识设备对应的驱动。次设备号由内核使用,用于确定设备文件所指的设备。

在内核中用dev_t类型来保存设备号。在Linux内核的2.6版本中,dev_t是一个32位的数,其中12为用来表示主设备号,而其余的20位用来表示次设备号。

Dev_t 类型:

//<linux/types.h>
typedef __u32 __kernel_dev_t;
typedef __kernel_dev_t		dev_t;

我们的代码不应该对设备编号的组织做任何假定,而应该始终使用<linux/kdev_t.h>中定义的宏来操作设备号。

MAJOR(dev_t dev); //由dev_t类型变量中解析出主设备号
MINOR(dev_t dev); //由dev_t类型变量中解析出次设备号
MKDEV(int major, int minor); //由主设备号和次设备号生成dev_t变量

在创建一个字符设备之前,驱动程序首先要做的就是申请设备号。有两个函数可以为字符设备分配设备号:

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---所申请的设备号对应的驱动程序名称。同大部分的内核函数一样,该函数在分配成功时返回0,在错误的情况下将返回一个负的错误码。

alloc_chrdev_region函数的四个参数:dev---指向输出的参数,在成功完成后将保存已分配范围的第一个编号。Baseminor---指定被请求的第一个次设备号。Count和name同register_chrdev_region函数是一样的。该函数的主设备号是内核动态分配的。

由于内核已经将部分设备号分配给了一些常见设备(可在源码中Documentation/devices.txt文件中查。并且也不知道将要运行驱动程序的主机上那些设备号已经被分配了。为了避免可能造成的冲突,我们应该尽量采用alloc_chrdev_region来申请设备号。

设备号也是属于一种系统资源,当不在需要设备号时需要进行释放。可以通过下面的函数释放设备号:

void unregister_chrdev_region(dev_t from, unsigned count);

通常在模块的清除函数中调用unregister_chrdev_region。

下面列出了通常的设备号申请代码:

#define MEMDEV_MAJOR 0
static int memdev_major = MEMDEV_MAJOR;
dev_t devno;
…
if (memdev_major) {
	devno = MKDEV(memdev_major, 0);
	ret = register_chrdev_region(devno, 1 , "memdev");
} else {
	ret = alloc_chrdev_region(&devno, 0, 1, "memdev");
	memdev_major = MAJOR(devno);
}

[1].《Linux设备驱动程序》第三版 Jonathan Corbet etc. 魏永明等译  中国电力出版社

[2].《深入理解Linux内核》第三版 Daniel P.Bovet etc. 陈莉君等译  中国电力出版社

[3].《Linux设备驱动开发详解》第二版  宋宝华  人民邮电出版社






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值