|
沙发

楼主 |
发表于 2009-8-26 22:00:25
|
只看该作者
有两个方法可以分配并初始化 cedv 结构。如果希望在运行时动态的获得一个独立的 cdev 结构,可以如下这么做:
struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;
cdev_alloc(void) 函数的代码为(对 cdev 结构体操作的系列函数可在 fs/char_dev.c 中找到):
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
} cdev_alloc() 的源代码可能由于内核版本号的不同而有差别(上面的代码为 2.6.30)
有时可能希望就把 cdev 结构内嵌在自己的特定设备结构里,那么在分配好 cdev 结构后,就用 cdev_init() 函数对其初始化:
void cdev_init (struct cdev *cdev, struct file_operations *fops)
cdev_init() 函数代码为:
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
} 另外,像 cdev 中的 owner 要设置为 THIS_MOULE 。
一旦 cdev 结构体设置完毕,最后一步就是要把这事告诉给内核,使用下面的函数:
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
cdev_add() 对应的代码为:
/**
* cdev_add() - add a char device to the system
* @p: the cdev structure for the device
* @dev: the first device number for which this device is responsible
* @count: the number of consecutive minor numbers corresponding to this
* device
*
* cdev_add() adds the device represented by @p to the system, making it
* live immediately. A negative error code is returned on failure.
*/
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
p->dev = dev;
p->count = count;
return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
} 参数 p 是 cdev 结构体的指针;
参数 dev 是设备响应的第一个设备号;
参数 count 和设备相关联的设备号的数目。
一般的,count 的值为 1,但是有些情形也可能是大于 1 的数。比如 SCSI 磁带机,它通过给每个物理设备安排多个此设备号来允许用户在应用程序里选择操作模式(比如密度)。
cdev_add 如果失败了,那么返回一个负值,表明驱动无法加载到系统中。然而它一般情况下都会成功,一旦 cdev_add 返回,设备也就 “活” 了起来,于是所对应的操作方法(file_operations 结构里所定义的各种函数)也就能为内核所调用。
从系统中移除一个字符设备,可以调用:
void cdev_del(struct cdev *p) |
|