linux字符设备驱动总结
/* TomooWang 个人读书总结 如有错误希望莅临查看的大侠给予斧正*/
1》
Linux2.6内核与2.4内核不同2.6内核采用了。cdev结构体来描述管理字符设备
struct cdev {
struct kobject kobj; //嵌在cdev结构中的kobject对象
struct module *owner;
struct file_operations *ops;/*file_operation 结构体,最终与硬件打交道的函数都注册在这里*/
struct list_head list;
dev_t dev;
unsigned int count;
};
与其相关的操作函数有:
void cdev_init(struct cdev *, struct file_operations *);
struct cdev *cdev_alloc(void);
void cdev_put(struct cdev *p);
int cdev_add(struct cdev *, dev_t, unsigned);
void cdev_del(struct cdev *);
void cd_forget(struct inode *);
cdev_alloc 返回cdev结构指针。
cdev_init 建立cdev 与 file_opreations 的联系
void cdev_init(struct cdev *cdev, struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
cdev->kobj.ktype = &ktype_cdev_default;
kobject_init(&cdev->kobj);
cdev->ops = fops;
}
cdev_add 调用后一个字符设备就被注册到系统中了。
要删除这个设备只需调用cdev_del函数
一般cdev_init 和 cdev_add 在设备加载函数中调用!cdev_del 一般在模块卸载函数中调用!
2》
设备号的分配。要使vfs系统调用能找到正确的open read write ioctl 等函数就要为设备分配一个独一无二的设备号(在inode中记录着这些东西,inode可理解为对应于物理磁盘上的具体对象。那么系统是怎样知道调用的是那个驱动程序呢。
系统是这样做的:
1.系统根据设备号记录在inode->i_rdev中, 在字符设备驱动模型中查找与之对应的驱动程序, 这通过kobj_lookup() 来实现这个函数会返回与设备号对应的cdev结构.
2.设置inode->i_cdev , 指向找到的cdev.
3. 将inode添加到cdev->list的链表中.
4. 使用cdev的ops 设置file对象的f_op
大家要注意到在只有在open等少数函数调用时才有inode节点出现,而 read write调用是没有inode节点。地四步)
2.6内核中注册申请设备号的函数为:
(1)静态申请:register_chrdev_region
(2)动态分配:alloc_chrdev_region
(3)释放设备号:unsigister_chrdev_rgion
3》file_operations 结构体。
file_operations结构体是字符设备的主体内容,也是驱动程序开发要实现的主体内容。其中包括了 Linux 中的open read write close mmap ioctl 等常用的函数。这些函数都需要自己来完成
4》用户空间与系统空间的数据交换。
linux的是用户空间和内核空间分开的(典型的分割为0~3G为用户空间 3G~4G为系统空间)由于系统的保护措施linux内核和用户空间之间不能直接访问,所以这里要借助一些函数来实现用户空间和系统空间的数据传递。常用的函数为:copy_to_user copy_from_user
阅读(1332) | 评论(0) | 转发(0) |