免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3026 | 回复: 10
打印 上一主题 下一主题

关于字符驱动的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-11 14:46 |只看该作者 |倒序浏览
本人linux新手,
最近看 《linux驱动程序设计》

第三章遇到问题实在无法理解,

file结构体里面的f_ops到底是什么,指向文件的当前位置,但他的具体值到底是什么?
他是指向一个结构体的指针吗?那用一个地址的值除以一个量子集的大小怎么能得到在链表结构中的具体位置item?

    int itemsize = quantum * qset;
   
    item = (long)*f_pos / itemsize;


因为没有先看内核,所以对内核的详细原理还不清楚,请哪位大哥帮帮忙啊
这个问题一直想不明白。


[ 本帖最后由 冰伊罗 于 2008-7-11 14:48 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-11 14:53 |只看该作者
你看书不够仔细。
好好看一下你自己的帖子!

论坛徽章:
0
3 [报告]
发表于 2008-07-11 14:57 |只看该作者
没看出什么问题啊?
能否请楼上的大哥详细说明下为什么可以这样算啊,这个问题我实在是看不明白了。

论坛徽章:
0
4 [报告]
发表于 2008-07-11 15:09 |只看该作者
我再详细点
把read函数的代码贴出来吧

ssize_t scull_read(struct file *filp, char __user *buf, size_t count,

                loff_t *f_pos)

{

    struct scull_dev *dev = filp->private_data;

    struct scull_qset *dptr;   

    int quantum = dev->quantum, qset = dev->qset;

    int itemsize = quantum * qset;

    int item, s_pos, q_pos, rest;

    ssize_t retval = 0;

    item = (long)*f_pos / itemsize;     //这里为什么要这样算??意图我知道,要计算出在scull_dev 链表中的位置,
                                      //但怎么能用指针值除以一个量子集的大小?这得出的是什么?为什么能这么算
                                       //呢?

    rest = (long)*f_pos % itemsize;

    s_pos = rest / quantum;
  
    q_pos = rest % quantum;
  
    dptr = scull_follow(dev, item);   //查找再链表中的当前位置


    if (count > quantum - q_pos)

        count = quantum - q_pos;


    if (copy_to_user(buf, dptr->data[s_pos] + q_pos, count)) {

        retval = -EFAULT;

        goto out;

    }

    *f_pos += count;

    retval = count;



  out:

    return retval;

}

[ 本帖最后由 冰伊罗 于 2008-7-11 15:11 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-07-11 16:27 |只看该作者
f_ops 和 f_pos 是同一个东西吗?

另外,你的 C 语言基础也不够扎实哦。

论坛徽章:
0
6 [报告]
发表于 2008-07-11 17:53 |只看该作者
?????
楼上的大哥??
我说的是file结构体里面的   f_pos;
第一个是我打错了,
能不能帮我解决问题?算我打错了,OK?
但你说的都没用啊,问题还没解决。。。。。。。
我又看了看,是一个64位的数值。这个值是什么?
是在private_data中的数据的大小值吗?

struct file {
       /*
         * fu_list becomes invalid after file_free is called and queued via
        * fu_rcuhead for RCU freeing
        */
         union {
                 struct list_head        fu_list;
                struct rcu_head         fu_rcuhead;
         } f_u;
         struct path             f_path;
#define f_dentry        f_path.dentry
#define f_vfsmnt        f_path.mnt
         const struct file_operations    *f_op;
         atomic_t                f_count;
        unsigned int            f_flags;
        mode_t                  f_mode;
       loff_t                  f_pos;
         struct fown_struct      f_owner;
         unsigned int            f_uid, f_gid;
        struct file_ra_state    f_ra;

       u64                     f_version;
#ifdef CONFIG_SECURITY
       void                    *f_security;
#endif
        /* needed for tty driver, and maybe others */
       void                    *private_data;

#ifdef CONFIG_EPOLL
       /* Used by fs/eventpoll.c to link all the hooks to this file */
         struct list_head        f_ep_links;
         spinlock_t              f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
         struct address_space    *f_mapping;
#ifdef CONFIG_DEBUG_WRITECOUNT
         unsigned long f_mnt_write_state;
#endif
};

[ 本帖最后由 冰伊罗 于 2008-7-11 17:54 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-07-11 18:02 |只看该作者
今天下午忙一直没看到回复

这个第三章我看了4天了。。。
因为内核部分缺陷不少,花了不少时间了
我自己按照这个思路自己写了一个例子,但是这个问题还是不明白,没人帮帮我吗?
不行只有自己printk打出来看看了。。。

论坛徽章:
0
8 [报告]
发表于 2008-07-11 23:40 |只看该作者
用 (long)*f_pos / itemsize 不就可以得出所求的位置在第几个 item 里面了吗?有何不理解?

论坛徽章:
0
9 [报告]
发表于 2011-04-11 18:35 |只看该作者
你看是不是这样?

论坛徽章:
0
10 [报告]
发表于 2011-04-11 19:01 |只看该作者
你的一个scull里面盛放的是一个链表scull_qset,一个链表又有许多的链表项(item)组成,而每个item中又存放了1000个指针(也就是这个item中数组的大小quanset),这些指针中,每个指针都可以指向一块内存,这块内存大小就是quantum(也就是书上讲的4000),那么,这一个item就可以操作的内存大小itemsize=(item中的指针数)*(每个指针可以指向的内存大小,也就是量子大小)=quanset*quantum=1000*4000,对吧?这个应该可以理解吧?
接下来我们看看(long) *f_pos,这个指针变量就是我们文件相对于文件起始位置的偏移量啊,用(long) *f_pos表示一个长整形,可以取的大小为0—2^64-1,这是文件的最大范围。注意不能超过他,否则goto out;我们假设现在这个数没有超过,那么,想一想,这个链表的每一项item所能操作的内存大小是多少?
不就是itemsize么?
如果你的这个(long)*f_pos超过一个itemsize怎么办?比如现在(long)*f_pos=4 000 001,那么当程序读完第一个item中的4000 000个字节以后,就要到链表项的第二个item开始读啊!对吧?那么我们怎么知道我要从第几个链表项开始读?
就用(long)*f_pos/itemsize 来算,还是刚才的假设,(long)*f_pos=4 000 001,又因为itemsize=4000 000
所以(long)*f_pos/itemsize =?应该为1,这不就是第二个链表项吗?注意,c语言从0开始计数(这个估计大家都知道,呵呵)。
在注意一下,刚才的(long)*f_pos/itemsize =1,那么(long)*f_pos%itemsize =?,也是1,这个是item中的偏移量,可以认为是哪个指针数组的偏移量,它就从第一个指针开始取数,第一个指针指向的是第二个item的第一个量子,ok


申明:因为本人也是菜鸟,所以可能解释的不一定对,希望大虾批评指正,谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP