zoukankan      html  css  js  c++  java
  • 【转】系统调用和驱动程序中相应函数的参数对应关系

    应用程序执行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);

    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 *);

    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);
    int (*open) (struct inode *, struct file *);

    可以看到,这些参数有很大一部分是相似的
    (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中的源代码:
     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 }    

    来源

  • 相关阅读:
    异常处理
    PAT——1048. 数字加密
    PAT——1047. 编程团体赛
    PAT——1046. 划拳
    PAT——1045. 快速排序(25)
    PAT——1044. 火星数字
    PAT——1043. 输出PATest
    PAT——1042. 字符统计
    PAT——1041. 考试座位号
    PAT——1040. 有几个PAT
  • 原文地址:https://www.cnblogs.com/skullboyer/p/9287449.html
Copyright © 2011-2022 走看看