系统调用跟驱动程序中相应函数的参数对应关系
系统调用和驱动程序中相应函数的参数对应关系
mine: 开关读写控(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 *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
driver:
int (*open) (struct inode *, struct file *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
系统调用 -> 内核框架处理后由框架再 -> 调用驱动中的相对应函数,所以系统调用的参数与驱动中的相对应函数不一样。
本文来自:http://blog.sina.com.cn/s/blog_6405313801012p9r.html
系统调用和驱动程序中相应函数的参数对应关系
应用程序执行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 *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
一个典型的file_operations结构实例:
static struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.read = hello_read,
.write = hello_write,
};
举例hello_write:
static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {
struct hello_android_dev* dev = filp->private_data;
ssize_t err = 0;
/*同步访问*/
if(down_interruptible(&(dev->sem))) {
return -ERESTARTSYS;
}
if(count != sizeof(dev->val)) {
goto out;
}
/*将用户提供的缓冲区的值写到设备寄存器去*/
if(copy_from_user(&(dev->val), buf, count)) {
err = -EFAULT;
goto out;
}
err = sizeof(dev->val);
out:
up(&(dev->sem));
return err;
}
可以看到,这些参数有很大一部分是相似的
(1) 系统调用open传入的参数已经被内核文件系统层处理了,在驱动程序中看不出原来的参数了;
(2)系统调用ioclt的参数个数可变,一般最多传入3个:后面两个参数与file_operations结构中ioctl成员的后面两个参数对应;
(3) 系统调用read传入的buf、count参数,对应file_operation结构中read成员的buf、count参数.而参数offp表示用户在文件中进行存取操作的位置,当执行完写操作后由驱动程序设置;
(4)系统调用write与file_operations结构中write成员的参数关系与(3)类似。
所有的系统调用(write,read)都是通过统一的“软中断”int80 同内核交互的,当需要使用系统调用时,用户空间的库函数将参数和系统调用号都压入到堆栈,然后执行int80切换到内核执行,内核再根据系统调用号和内核符号表得到对应的内核执行代码,比如write在内核内对应的代码就是sys_write。至于参数,在内核处理过程中会将用户空间的参数转化为内核所表示的形式。你可以看看write的汇编源代码,好像在libc里面,通过ar命令可以提取出来。
驱动程序里的write函数有四个参数,函数格式如下:
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中的源代码:
asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count) {
ssize_t ret;
struct file * file;
struct inode * inode;
ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
lock_kernel();
ret = -EBADF;
file = fget(fd);
if (!file)
goto bad_file;
if (!(file->f_mode & FMODE_WRITE))
goto out;
inode = file->f_dentry->d_inode;
ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, file->f_pos,
count);
if (ret)
goto out;
ret = -EINVAL;
if (!file->f_op || !(write = file->f_op->write))
goto out;
down(&inode->i_sem);
ret = write(file, buf, count, &file->f_pos);
up(&inode->i_sem);
out: fput(file);
bad_file: unlock_kernel();
return ret;
}
mine: 开关读写控(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 *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
driver:
int (*open) (struct inode *, struct file *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
系统调用 -> 内核框架处理后由框架再 -> 调用驱动中的相对应函数,所以系统调用的参数与驱动中的相对应函数不一样。
本文来自:http://blog.sina.com.cn/s/blog_6405313801012p9r.html
系统调用和驱动程序中相应函数的参数对应关系
应用程序执行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 *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
一个典型的file_operations结构实例:
static struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.read = hello_read,
.write = hello_write,
};
举例hello_write:
static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {
struct hello_android_dev* dev = filp->private_data;
ssize_t err = 0;
/*同步访问*/
if(down_interruptible(&(dev->sem))) {
return -ERESTARTSYS;
}
if(count != sizeof(dev->val)) {
goto out;
}
/*将用户提供的缓冲区的值写到设备寄存器去*/
if(copy_from_user(&(dev->val), buf, count)) {
err = -EFAULT;
goto out;
}
err = sizeof(dev->val);
out:
up(&(dev->sem));
return err;
}
可以看到,这些参数有很大一部分是相似的
(1) 系统调用open传入的参数已经被内核文件系统层处理了,在驱动程序中看不出原来的参数了;
(2)系统调用ioclt的参数个数可变,一般最多传入3个:后面两个参数与file_operations结构中ioctl成员的后面两个参数对应;
(3) 系统调用read传入的buf、count参数,对应file_operation结构中read成员的buf、count参数.而参数offp表示用户在文件中进行存取操作的位置,当执行完写操作后由驱动程序设置;
(4)系统调用write与file_operations结构中write成员的参数关系与(3)类似。
所有的系统调用(write,read)都是通过统一的“软中断”int80 同内核交互的,当需要使用系统调用时,用户空间的库函数将参数和系统调用号都压入到堆栈,然后执行int80切换到内核执行,内核再根据系统调用号和内核符号表得到对应的内核执行代码,比如write在内核内对应的代码就是sys_write。至于参数,在内核处理过程中会将用户空间的参数转化为内核所表示的形式。你可以看看write的汇编源代码,好像在libc里面,通过ar命令可以提取出来。
驱动程序里的write函数有四个参数,函数格式如下:
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中的源代码:
asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count) {
ssize_t ret;
struct file * file;
struct inode * inode;
ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
lock_kernel();
ret = -EBADF;
file = fget(fd);
if (!file)
goto bad_file;
if (!(file->f_mode & FMODE_WRITE))
goto out;
inode = file->f_dentry->d_inode;
ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, file->f_pos,
count);
if (ret)
goto out;
ret = -EINVAL;
if (!file->f_op || !(write = file->f_op->write))
goto out;
down(&inode->i_sem);
ret = write(file, buf, count, &file->f_pos);
up(&inode->i_sem);
out: fput(file);
bad_file: unlock_kernel();
return ret;
}