简单的字符串驱动程序 (读《linux驱动程序》)

1.主设备号和次设备号

下图中,“”5月”的前两列分别是主设备号和次设备号,主设备号用来标识设备对应的驱动程序,次设备号用来确定设备文件所指的设备。

在内核,dev_t类型用来保存设备编号,位于文件<linux/types.h>。目前版本(3.1),dev_t 是一个unsigned int 类型,12位用来标识主版本号,20位用来标识次版本号,使用 MAJOR(dev_t dev)MINOR (dev_t dev)两个宏来获取主版本号和次版本号.  使用MKDEV(int major,int minor) 获取dev_t类型的版本号。

主版本号的静态分配和动态分配:

在2.4版本之前,使用register_chrdev(unsigned int major, const char *name,const struct file_operations *fops); 进行注册,如果major 为0则自动分配 主版本号。

静态分配 , 使用 register_chrdev_region(dev_t first,unsigned int count, char * name) ;

动态分配,使用 alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char * name);

2.文件操作

struct file_operations 

通过上面的操作获取了设备号,但是还没有将任何驱动程序链接到 你获取的设备号,linux内核采用 struct file_operations  <linux/fs.h>来建立连接,这个结构定义了一些列的文件操作的函数指针,例如open read write,ioctl 等,是不是很熟悉? 用户程序调用了 open read 等系统调用,然后经过 VFS层,在vfs层拿到 struct file 指针,通过调用f_op(struct file_operations )的函数指针实现驱动程序的调用,详情请参见read_write.c。

struct file

file结构代表一个打开的文件,它有内核在调用open 时创建,直到最后的close函数,在文件的所有实例都被关闭之后内核才会释放、

struct inode

内核用inode表示文件,与file 不同的是,file 随着open 系统调用的多次调用打开同一个文件,内核中会有多个struct file的实例,但是inode实例只有一个。

dev_t i_rdev  设备号,这个字段的类型在2.5中发生了变化,为了兼容性,内核中增加了两个新的宏,用来获取主、次设备号

unsigned int iminor(struct inode * inode);

unsigned int imajor(struct inode * inode);

3.注册驱动

初始化

使用struct cdev <linux/cdev.h>结构来标示字符串设备, struct cdev 结构有两种初始化方式, struct cdev * cdev_alloc()和 void cdev_init(struct cdev * cdev, struct file_operations * fops)。

添加

使用 int cdev_add(struct cdev * cdev, dev_t num, unsigned int count);

删除

使用 void cdev_del(struct cdev * cdev);

4.用户态与内核态的数据交互。

unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) ;

unsigned long copy_to_user(void __user *to, const void *from, unsigned long n);

猜你喜欢

转载自www.cnblogs.com/mcran/p/10884436.html