应用程序执行open、ioctl等系统调用,它们的参数和驱动程序中相应函数的参数不是一一对应的,其中经过了内核文件系统层的转换。
int open(const char *pathname,int flags)
int ioctl(int d,int request,....)
ssize_t read(int fd,void *buf,size_t count)
ssize_t write(int fd,const void *buf,size_t count);
|
file_operations结构中的成员如下:
int (*open) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
|
short_write (struct inode *inode, struct file *filp, const char *buf, int count)
而用户程序中的write函数只有三个参数,函数格式如下:
write(inf fd, char *buf, int count)
那他们两个是怎么联系在一起的呢?这就要靠操作系统核心中的函数sys_write了,下面
是Linux Kernel 2.2.14中sys_write中的源代码:
1 asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count) 2 { 3 ssize_t ret; 4 struct file * file; 5 struct inode * inode; 6 ssize_t (*write)(struct file *, const char *, size_t, loff_t *); /* 指向驱动程序中的wirte函数的指针*/ 7 8 lock_kernel(); 9 10 ret = -EBADF; 11 file = fget(fd); /* 通过文件描述符得到文件指针 */ 12 if (!file) 13 goto bad_file; 14 15 if (!(file->f_mode & FMODE_WRITE)) 16 goto out; 17 18 inode = file->f_dentry->d_inode; /* 得到inode信息 */ 19 ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, file->f_pos, count); 20 if (ret) 21 goto out; 22 ret = -EINVAL; 23 if (!file->f_op || !(write = file->f_op->write)) /* 将函数开始时声明的write函数指针指向fops方法中对应的write函数 */ 24 goto out; 25 down(&inode->i_sem); 26 ret = write(file, buf, count, &file->f_pos); /* 使用驱动程序中的write函数将数据输入设备,注意看,这里就是四个参数了 */ 27 up(&inode->i_sem); 28 29 out: 30 fput(file); 31 bad_file: 32 unlock_kernel(); 33 return ret; 34 }
【来源】