【linux内核分析与应用-陈莉君】字符设备驱动
生活随笔
收集整理的這篇文章主要介紹了
【linux内核分析与应用-陈莉君】字符设备驱动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
?
1.什么是字符設備
2.如何來描述字符設備
3 struct cdev與const struct file_operations之間的關系
4.struct file_operations源碼
5.字符設備驅動框架
6.編寫字符設備驅動的步驟
7.字符設備結構
8.字符設備驅動程序的注冊
9.從系統調用到驅動程序
10.用戶空間與內核空間數據的傳送
11.參考資料與思考問題
1.什么是字符設備
字符設備是指只能一個一個字節進行讀寫操作的設備,不能隨機讀取設備中的每一個數據,取數據要 按照先后次序來進行,字符設備時面向流的設備,常見的字符設備有: 鼠標, 鍵盤, 串口, 控制臺, led等.一般每一個字符設備或者塊設備都會在dev目錄下對應一個設備文件,Linux用戶層程序通過設備文件來使用 驅動程序,操作字符設備或者塊設備.2.如何來描述字符設備
?
D:\005-代碼\001-開源項目源碼\004-內核源碼\linux-4.15.1\linux-4.15.1\include\linux\types.h typedef unsigned int __u32; typedef __u32 __kernel_dev_t; typedef __kernel_dev_t dev_t;問題:為什么不直接寫成 typedef unsigned int dev_t;D:\005-代碼\001-開源項目源碼\004-內核源碼\linux-4.15.1\linux-4.15.1\include\linux\cdev.h struct cdev {struct kobject kobj; // 內嵌的內核對象struct module *owner;// 該字符設備所在的內核模塊(所有者)的對象指針const struct file_operations *ops;// 字符設備所能實現的操作表struct list_head list;// 用來將已經向內核注冊的所有字符設備形成鏈表dev_t dev;//字符設備的設備號,由主設備號和次設備號構成(如果是一次申請多個設備號,此設備號為第一個),主設備號12位,次設備號20位unsigned int count; // 隸屬于同一主設備號的次設備號的個數 } __randomize_layout;3 struct cdev與const struct file_operations之間的關系
4.struct file_operations源碼
E:\004-代碼\002-內核源碼\linux-4.15.1\linux-4.15.1\include\linux\fs.h construct file_operations {struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);int (*iterate) (struct file *, struct dir_context *);int (*iterate_shared) (struct file *, struct dir_context *);unsigned int (*poll) (struct file *, struct poll_table_struct *);long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);long (*compat_ioctl) (struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);unsigned long mmap_supported_flags;int (*open) (struct inode *, struct file *);int (*flush) (struct file *, fl_owner_t id);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, loff_t, loff_t, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);int (*check_flags)(int);int (*flock) (struct file *, int, struct file_lock *);ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);int (*setlease)(struct file *, long, struct file_lock **, void **);long (*fallocate)(struct file *file, int mode, loff_t offset,loff_t len);void (*show_fdinfo)(struct seq_file *m, struct file *f); #ifndef CONFIG_MMUunsigned (*mmap_capabilities)(struct file *); #endifssize_t (*copy_file_range)(struct file *, loff_t, struct file *,loff_t, size_t, unsigned int);int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,u64);ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,u64); } __randomize_layout;從源碼中可以看出,每個字段都是一個函數,都是指向VFS層所調用的系統調用所對應的函數.?
5.字符設備驅動框架
6.編寫字符設備驅動的步驟
?
cdev_alloc()--動態申請或構造cdev內存 cdev_init() --初始化函數,初始化cdev的成員并且建立起cdev與file_operations之間的關聯關系 cdev_add() --注冊cdev設備對象,也就是添加cdev對象到字符設備列表中 cdev_del() --將cdev對象從系統中刪除,也就是注銷 cdev_put() --釋放cdev內存設備號的申請與釋放 一個字符設備或者一個塊設備都有一個主設備號和一個次設備號,主設備號用來標識與設備文件相連的 驅動程序,用來反映設備的類型,次設備號被驅動程序用來辨別操作的到底是哪一個設備,用來區分同類 型的設備,在這里給出三個宏和三個函數分別從設備號中提取主設備號和次設備號,將主設備號和次設 備號拼湊成設備號,靜態地申請設備號,動態地申請設備號以及釋放設備號.7.字符設備結構
問題:struct char_device_struct與struct cdev有什么關系?8.字符設備驅動程序的注冊
這個cdrdevs就是字符設備表.9.從系統調用到驅動程序
10.用戶空間與內核空間數據的傳送
11.參考資料與思考問題
?
總結
以上是生活随笔為你收集整理的【linux内核分析与应用-陈莉君】字符设备驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 镜像封装和添加驱动
- 下一篇: Linux设备驱动入门