简单字符驱动设备

雨点打透心脏的1/2处 2022-06-16 00:15 330阅读 0赞
  1. scull 字符设备驱动程序的设备描述
  2. 字符设备驱动程序是分配一段内存,然后提供对这个设备的管理方式,我们通过它提供的操作来操纵字符驱动设备,本质上是一个我们分配的模拟内存来模拟驱动设备。
  3. 结构如下:
  4. 几个重要方法,我们最初只提供几个简单的接口函数。
  5. read : 拷贝数据到应用程序空间。
  6. write: 拷贝数据到内核空间,在这里就是我们的字符驱动设备。
  7. open : 打开并且初始化设备。
  8. 字符设备驱动程序几个重要的数据结构:
  9. ```
  10. struct scull_dev {
  11. struct scull_qset *data; /* Pointer to first quantum set */
  12. int quantum; /* the current quantum size */
  13. int qset; /* the current array size */
  14. unsigned long size; /* amount of data stored here */
  15. unsigned int access_key; /* used by sculluid and scullpriv */
  16. struct semaphore sem; /* mutual exclusion semaphore */
  17. struct cdev cdev; /* Char device structure */
  18. };
  19. ```
  20. ```
  21. struct cdev {
  22. struct kobject kobj;
  23. struct module *owner;
  24. const struct file_operations *ops;
  25. struct list_head list;
  26. dev_t dev;
  27. unsigned int count;
  28. };
  29. ```
  30. ```
  31. struct inode {
  32. umode_t i_mode;
  33. unsigned short i_opflags;
  34. kuid_t i_uid;
  35. kgid_t i_gid;
  36. unsigned int i_flags;
  37. #ifdef CONFIG_FS_POSIX_ACL
  38. struct posix_acl *i_acl;
  39. struct posix_acl *i_default_acl;
  40. #endif
  41. const struct inode_operations *i_op;
  42. struct super_block *i_sb;
  43. struct address_space *i_mapping;
  44. #ifdef CONFIG_SECURITY
  45. void *i_security;
  46. #endif
  47. /* Stat data, not accessed from path walking */
  48. unsigned long i_ino;
  49. /*
  50. * Filesystems may only read i_nlink directly. They shall use the
  51. * following functions for modification:
  52. *
  53. * (set|clear|inc|drop)_nlink
  54. * inode_(inc|dec)_link_count
  55. */
  56. union {
  57. const unsigned int i_nlink;
  58. unsigned int __i_nlink;
  59. };
  60. dev_t i_rdev;
  61. loff_t i_size;
  62. struct timespec i_atime;
  63. struct timespec i_mtime;
  64. struct timespec i_ctime;
  65. spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
  66. unsigned short i_bytes;
  67. unsigned int i_blkbits;
  68. blkcnt_t i_blocks;
  69. #ifdef __NEED_I_SIZE_ORDERED
  70. seqcount_t i_size_seqcount;
  71. #endif
  72. /* Misc */
  73. unsigned long i_state;
  74. struct mutex i_mutex;
  75. unsigned long dirtied_when; /* jiffies of first dirtying */
  76. unsigned long dirtied_time_when;
  77. struct hlist_node i_hash;
  78. struct list_head i_io_list; /* backing dev IO list */
  79. #ifdef CONFIG_CGROUP_WRITEBACK
  80. struct bdi_writeback *i_wb; /* the associated cgroup wb */
  81. /* foreign inode detection, see wbc_detach_inode() */
  82. int i_wb_frn_winner;
  83. u16 i_wb_frn_avg_time;
  84. u16 i_wb_frn_history;
  85. #endif
  86. struct list_head i_lru; /* inode LRU list */
  87. struct list_head i_sb_list;
  88. union {
  89. struct hlist_head i_dentry;
  90. struct rcu_head i_rcu;
  91. };
  92. u64 i_version;
  93. atomic_t i_count;
  94. atomic_t i_dio_count;
  95. atomic_t i_writecount;
  96. #ifdef CONFIG_IMA
  97. atomic_t i_readcount; /* struct files open RO */
  98. #endif
  99. const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
  100. struct file_lock_context *i_flctx;
  101. struct address_space i_data;
  102. struct list_head i_devices;
  103. union {
  104. struct pipe_inode_info *i_pipe;
  105. struct block_device *i_bdev;
  106. struct cdev *i_cdev;
  107. char *i_link;
  108. };
  109. __u32 i_generation;
  110. #ifdef CONFIG_FSNOTIFY
  111. __u32 i_fsnotify_mask; /* all events this inode cares about */
  112. struct hlist_head i_fsnotify_marks;
  113. #endif
  114. void *i_private; /* fs or device private pointer */
  115. };
  116. ```
  117. ```
  118. struct file {
  119. union {
  120. struct llist_node fu_llist;
  121. struct rcu_head fu_rcuhead;
  122. } f_u;
  123. struct path f_path;
  124. struct inode *f_inode; /* cached value */
  125. const struct file_operations *f_op;
  126. /*
  127. * Protects f_ep_links, f_flags.
  128. * Must not be taken from IRQ context.
  129. */
  130. spinlock_t f_lock;
  131. atomic_long_t f_count;
  132. unsigned int f_flags;
  133. fmode_t f_mode;
  134. struct mutex f_pos_lock;
  135. loff_t f_pos;
  136. struct fown_struct f_owner;
  137. const struct cred *f_cred;
  138. struct file_ra_state f_ra;
  139. u64 f_version;
  140. #ifdef CONFIG_SECURITY
  141. void *f_security;
  142. #endif
  143. /* needed for tty driver, and maybe others */
  144. void *private_data;
  145. #ifdef CONFIG_EPOLL
  146. /* Used by fs/eventpoll.c to link all the hooks to this file */
  147. struct list_head f_ep_links;
  148. struct list_head f_tfile_llink;
  149. #endif /* #ifdef CONFIG_EPOLL */
  150. struct address_space *f_mapping;
  151. } __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
  152. struct file_handle {
  153. __u32 handle_bytes;
  154. int handle_type;
  155. /* file identifier */
  156. unsigned char f_handle[0];
  157. };
  158. ```
  159. ```
  160. struct file_operations {
  161. struct module *owner;
  162. loff_t (*llseek) (struct file *, loff_t, int);
  163. ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
  164. ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
  165. ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
  166. ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
  167. int (*iterate) (struct file *, struct dir_context *);
  168. unsigned int (*poll) (struct file *, struct poll_table_struct *);
  169. long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
  170. long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
  171. int (*mmap) (struct file *, struct vm_area_struct *);
  172. int (*open) (struct inode *, struct file *);
  173. int (*flush) (struct file *, fl_owner_t id);
  174. int (*release) (struct inode *, struct file *);
  175. int (*fsync) (struct file *, loff_t, loff_t, int datasync);
  176. int (*aio_fsync) (struct kiocb *, int datasync);
  177. int (*fasync) (int, struct file *, int);
  178. int (*lock) (struct file *, int, struct file_lock *);
  179. ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
  180. unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
  181. int (*check_flags)(int);
  182. int (*flock) (struct file *, int, struct file_lock *);
  183. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
  184. ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
  185. int (*setlease)(struct file *, long, struct file_lock **, void **);
  186. long (*fallocate)(struct file *file, int mode, loff_t offset,
  187. loff_t len);
  188. void (*show_fdinfo)(struct seq_file *m, struct file *f);
  189. #ifndef CONFIG_MMU
  190. unsigned (*mmap_capabilities)(struct file *);
  191. #endif
  192. };
  193. ```
  194. 设备驱动程序设计的基本框架
  195. 正在上传…
  196. 取消
  197. 1.申请设备号,主,次设备号。
  198. 2.构建我们的设备结构。
  199. 3.编写fops的内核提供的操作方法,更新fops指针。
  200. 4.注册我们的设备。
  201. 测试结果
  202. 我们可以看到,当给我们的scull新设备写入数据的时候,使用free命令就可以看到内存被成功占用。
  203. 这里有一个重要问题:
  204. 如何安全的将数据在用户空间和逻辑空间之间拷贝?
  205. 解决方法:内核提供了安全的拷贝函数:
  206. copy_to_user
  207. copy_from_user
  208. 关于这两个函数有一篇博客描述的比较清楚:
  209. http://blog.csdn.net/ce123_zhouwei/article/details/8454226
  210. unsigned long copy_to_user(void __user *to, const void *from, unsigned long n);
  211. 如果数据拷贝成功,则返回零;否则,返回没有拷贝成功的数据字节数。
  212. *to是用户空间的指针,
  213. *from是内核空间指针,
  214. n表示从内核空间向用户空间拷贝数据的字节数。
  215. 功能:用于将用户空间的数据传送到内核空间。
  216. unsigned long copy_from_user(void * to, const void __user * from, unsigned long n)
  217. 第一个参数to是内核空间的数据目标地址指针,
  218. 第二个参数from是用户空间的数据源地址指针,
  219. 第三个参数n是数据的长度。
  220. 如果数据拷贝成功,则返回零;否则,返回没有拷贝成功的数据字节数。
  221. 此函数将from指针指向的用户空间地址开始的连续n个字节的数据产送到to指针指向的内核空间地址.

发表评论

表情:
评论列表 (有 0 条评论,330人围观)

还没有评论,来说两句吧...

相关阅读