n 文件操作file_operations
u <linux/fs.h>中定義file_operations。
u __user表明指針是一個用戶空間地址,因此不能被直接引用。
u ssize_t (*aio_write)(struct kiocb *, const char _ _user *, size_t,
loff_t *); 初始化設備上的異步寫入操作。
u unsigned int (*poll) (struct file *, struct poll_table_struct *);
是poll、epoll和select這三個系統(tǒng)調用的后端實現(xiàn)??捎脕聿樵兡硞€或多個文件描述符
上的讀取或寫入是否會被阻塞。
u int (*mmap) (struct file *, struct vm_area_struct *);
用于請求將設備內存映射到進程地址空間。
u int (*fsync) (struct file *, struct dentry *, int);
用戶調用它來刷新待處理的數(shù)據(jù)。
u int (*fasync) (int, struct file *, int);
用來通知設備其FASYNC標志發(fā)生了變化。
file結構
u struct file是一個內核結構,不會出現(xiàn)在用戶程序中
inode結構
u 內核用inode結構在內部表示文件,因此它和file結構不同,后者表示打開的文件描述符。
對單個文件,可能會有許多個表示打開的文件描述符的file結構,但它們都指向單個inode
結構。
u dev_t i_rdev:對表示設備文件的inode結構,該字段包含了真正的設備編號。
u struct cdev *i_cdev;struct cdev表示字符設備的內核的內部結構。
當inode指向一個字符設備文件時,該字段包含了指向struct cdev結構的指針
u unsigned int iminor(struct inode *inode);
u unsigned int imajor(struct inode *inode);
用來從一個inode中獲得主設備號和次設備號
※ 字符設備的注冊
n 內核內部使用struct cdev結構來表示字符設備。為此我們的代碼應包含<linux/cdev.h>,
其中定義了這個結構以及與其相關的一些輔助函數(shù)。
※ The classic way to register a char device driver is with:
int register_chrdev(unsigned int major, const char *name,
struct file_operations *fops);
int unregister_chrdev(unsigned int major, const char *name);
※ open方法
n 在大部分驅動程序中,open完成如下工作:
u 檢查設備相關錯誤(諸如設備未就緒或相似的硬件問題)。
u 如果是首次打開,初始化設備。
u 標別次設備號,如有必要更新f_op指針。
u 分配和填寫要放在filp->private_data里的數(shù)據(jù)結構。
u 增加使用計數(shù)。
container_of(pointer, container_type, container_field);
struct scull_dev *dev; /* device information */
dev = container_of(inode->i_cdev, struct scull_dev, cdev);
filp->private_data = dev; /* for other methods */
※ release方法的作用正好與open相反。這個設備方法有時也稱為close。它應該:
n 使用計數(shù)減1。
n 釋放open分配在filp->private_data中的內存。
n 在最后一次關閉操作時關閉設備。
※ The scull driver introduces two core functions used to manage memory in the Linux kernel. These functions,
defined in <linux/slab.h>, are:
void *kmalloc(size_t size, int flags);
void kfree(void *ptr);
※ 在scull中,每個設備都是一個指針鏈表,其中每個指針都指向一個scull_qset結構。默認情況下,每一個這樣的結構通過一個中間指針數(shù)組最多可引用4000000個字節(jié)。使用了一個有1000個指針的數(shù)組,每個指針指向一個4000字節(jié)的區(qū)域。
※ 量子是什么??P65 每個量子占用4000個字節(jié)
※ 使用宏和整數(shù)值同時允許在編譯期間和加載階段進行配置,這種方法和前面選擇主設備號的方法類似。對于驅動程序中任何不確定的或與策略相關的數(shù)值,我們都可以使用這種技巧。