字符设备驱动
重要概念:
dev_t:内核中用来表示设备编号的数据类型
通过设备编号获得主、次设备号
1 //dev_t dev;
2 #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
3 #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
由主、次设备号构造设备编号
1 #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
"文件系统"头文件,它是编写设备驱动程序必须包含的头文件,声明了大量重要的函数和数据结构
1 #include <linux/fs.h>
大多数设备驱动程序会用到的、三个重要的数据结构;
1 struct inode *inode; //内核用inode结构在内部表示文件
2 struct file *file; //代表一个打开的文件
3 struct file_operations *fops; //用于使设备编号与驱动程序操作建立联系
特别说明,对于struct inode,我们只关注两个元素:
inode->i_rdev; //dev_t i_rdev; 表示设备文件的inode结构, 包含了真正的设备编号;
inode->i_cdev; //struct cdev *i_cdev; 表示了字符设的内核的内部结构
一个方便使用的宏,用于从包含在某个结构中的指针,获得结构本身的指针
1 #include <linux/kernel.h>
2 #define container_of(ptr, type, member) ({ \
3 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
4 (type *)( (char *)__mptr - offsetof(type,member) );})
该头文件声明了在内核代码和用户空间之间传递数据的函数
1 #include <asm/uaccess.h>
在用户空间和内核空间之间拷贝数据
1 unsigned long copy_from_user(void *to, const void *from, unsigned long count);
2 unsigned long copy_to_user(void *to, const void *from, unsigned long count);
部分函数接口:
1 /**
2 * register_chrdev() - Register a major number for character devices.
3 * @major: major device number or 0 for dynamic allocation
4 * @name: name of this range of devices
5 * @fops: file operations associated with this devices
6 *
7 * If @major == 0 this functions will dynamically allocate a major and return
8 * its number.
9 *
10 * If @major > 0 this function will attempt to reserve a device with the given
11 * major number and will return zero on success.
12 *
13 * Returns a -ve errno on failure.
14 *
15 * The name of this device has nothing to do with the name of the device in
16 * /dev. It only helps to keep track of the different owners of devices. If
17 * your module name has only one type of devices it's ok to use e.g. the name
18 * of the module here.
19 *
20 * This function registers a range of 256 minor numbers. The first minor number
21 * is 0.
22 */
23 int register_chrdev(unsigned int major, const char *name,
24 const struct file_operations *fops);
25
26 int unregister_chrdev(unsigned int major, const char *name);
unsigned int iminor(struct inode *inode);
unsigned int imajor(struct inode *inode);
应用程序与内核代码之间的联系