linux kernel —— 字符设备

cdev结构体

1. 在Linux内核中,使用cdev结构体描述一个字符设备, 其中比较重要的就是file_operation结构体, 它不仅能够实现打开本设备, 还能在当前设备的基础上打开其他的设备, 这一切都取决于再文件打开函数里定义的文件指针。

1 struct cdev {
2     struct kobject kobj;  
3     struct module *owner;        /*to which module it belongs*/
4     struct file_operations *ops; /* file operation  struct*/
5     struct list_head list;
6     dev_t dev;                        /*device number*/
7     unsigned int count;
8 };

 cdev的struct中dev_t成员定义了设备号,为32位,其中主设备号有12位,次设备号有20位,用下列宏可以获取主次设备号:

1 MAJOR(dev_t dev)
2 MINOR(dev_t dev)

反过来,可以根据以下宏和已知的主次设备号生成dev_t:

MKDEV(int major, int minor)

2. linux内核提供了一组函数以用于操作cdev结构体:

void cdev_init(struct cdev *, struct file_operations *);/*初始化cdev成员,并建立cdev和file_operations之间的连接*/
struct cdev *cdev_alloc(void); /*动态申请一个cdev内存*/
void cdev_put(struct cdev *p);
int cdev_add(struct cdev *, dev_t, unsigned); /*向设备添加一个cdev,注册*/
void cdev_del(struct cdev *);    /*向系统删除一个cdev,注销*/

 

3. 在cdev结构体中的另一个重要成员是file_operations, 它定义了字符设备驱动提供给虚拟文件系统的接口函数(API)。

复制代码
 1 struct file_operations { 
 2 
 3     struct module *owner; 
 4 
 5     loff_t (*llseek) (struct file *, loff_t, int); 
 6 
 7     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 
 8 
 9     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 
10 
11     ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); 
12 
13     ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); 
14 
15     int (*iopoll)(struct kiocb *kiocb, bool spin); 
16 
17     int (*iterate) (struct file *, struct dir_context *); 
18 
19     int (*iterate_shared) (struct file *, struct dir_context *); 
20 
21     __poll_t (*poll) (struct file *, struct poll_table_struct *); 
22 
23     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 
24 
25     long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 
26 
27     int (*mmap) (struct file *, struct vm_area_struct *); 
28 
29     unsigned long mmap_supported_flags; 
30 
31     int (*open) (struct inode *, struct file *); 
32 
33     int (*flush) (struct file *, fl_owner_t id); 
34 
35     int (*release) (struct inode *, struct file *); 
36 
37     int (*fsync) (struct file *, loff_t, loff_t, int datasync); 
38 
39     int (*fasync) (int, struct file *, int); 
40 
41     int (*lock) (struct file *, int, struct file_lock *); 
42 
43     ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 
44 
45     unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 
46 
47     int (*check_flags)(int); 
48 
49     int (*flock) (struct file *, int, struct file_lock *); 
50 
51     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 
52 
53     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 
54 
55     int (*setlease)(struct file *, long, struct file_lock **, void **); 
56 
57     long (*fallocate)(struct file *file, int mode, loff_t offset, 
58 
59         loff_t len); 
60 
61     void (*show_fdinfo)(struct seq_file *m, struct file *f); 
62 
63     ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, 
64 
65         loff_t, size_t, unsigned int); 
66 
67     loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in, 
68 
69              struct file *file_out, loff_t pos_out, 
70 
71              loff_t len, unsigned int remap_flags); 
72 
73     int (*fadvise)(struct file *, loff_t, loff_t, int); 
74 
75 } __randomize_layout;
复制代码

 

Note:

1. any member of the structure which you do not explicitly assign will be initialized to NULL by gcc.

2.Linux v5.6, the proc_ops structure was introduced to replace the use of the file_operations structure when registering proc handlers.

 

posted @   七块蛋糕  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示