Chinaunix首页 | 论坛 | 博客
  • 博客访问: 119901
  • 博文数量: 15
  • 博客积分: 1581
  • 博客等级: 上尉
  • 技术积分: 411
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-29 09:48
文章分类

全部博文(15)

文章存档

2011年(8)

2010年(7)

我的朋友

分类: LINUX

2010-08-08 16:24:47


file结构体,代表一个打开的文件,与用户空间的FILE不一样。有open于内核创建。
 

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;

    unsigned long 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;
};


inode 结构由内核在内部用来表示文件. 因此, 它和代表打开文件描述符的文
件结构是不同的. 可能有代表单个文件的多个打开描述符的许多文件结构, 但
是它们都指向一个单个 inode 结构.

struct inode {
    struct hlist_node i_hash;
    struct list_head i_list;
    struct list_head i_sb_list;
    struct list_head i_dentry;
    unsigned long i_ino;
    atomic_t i_count;
    unsigned int i_nlink;
    uid_t i_uid;
    gid_t i_gid;
    dev_t i_rdev;
    unsigned long i_version;
    loff_t i_size;
#ifdef __NEED_I_SIZE_ORDERED
    seqcount_t i_size_seqcount;
#endif
    struct timespec i_atime;
    struct timespec i_mtime;
    struct timespec i_ctime;
    unsigned int i_blkbits;
    blkcnt_t i_blocks;
    unsigned short i_bytes;
    umode_t i_mode;
    spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
    struct mutex i_mutex;
    struct rw_semaphore i_alloc_sem;
    struct inode_operations *i_op;
    const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
    struct super_block *i_sb;
    struct file_lock *i_flock;
    struct address_space *i_mapping;
    struct address_space i_data;
#ifdef CONFIG_QUOTA
    struct dquot *i_dquot[MAXQUOTAS];
#endif
    struct list_head i_devices;
    union {
        struct pipe_inode_info *i_pipe;
        struct block_device *i_bdev;
        struct cdev *i_cdev;
    };
    int i_cindex;

    __u32 i_generation;

#ifdef CONFIG_DNOTIFY
    unsigned long i_dnotify_mask; /* Directory notify events */
    struct dnotify_struct *i_dnotify; /* for directory notifications */
#endif

#ifdef CONFIG_INOTIFY
    struct list_head inotify_watches; /* watches on this inode */
    struct mutex inotify_mutex; /* protects the watches list */
#endif

    unsigned long i_state;
    unsigned long dirtied_when; /* jiffies of first dirtying */

    unsigned int i_flags;

    atomic_t i_writecount;
#ifdef CONFIG_SECURITY
    void *i_security;
#endif
    void *i_private; /* fs or device private pointer */
};



3.4 字符设备的注册

内核在内部使用类型 struct cdev 的结构来代表字符设备. 在内核调用你的设备操作前, 你编写分配并注册一个或几个这些结构.为此,你的代码应当包含 , 这个结构和它的关联帮助函数定义在这里.(原话)。

 

struct cdev {
        struct kobject kobj;
        struct module *owner; //所属模块

        const struct file_operations *ops;
                //文件操作结构,在写驱动时,其结构体内的大部分函数要被实现

        struct list_head list;
        dev_t dev; //设备号,int 类型,高12位为主设备号,低20位为次设备号

        unsigned int count;
};

//独立初始化cdev

 struct cdev *my_cdev = cdev_alloc();
  my_cdev->ops = &my_fops;
//通知内核

int cdev_add(struct cdev *dev, dev_t num, unsigned int count);

scull 中的设备注册

struct scull_dev {
 struct scull_qset *data; /* Pointer to first quantum set */
 int quantum; /* the current quantum size */
 int qset; /* the current array size */
 unsigned long size; /* amount of data stored here */
 unsigned int access_key; /* used by sculluid and scullpriv */
 struct semaphore sem; /* mutual exclusion semaphore */
struct cdev cdev; /* Char device structure */
};

我们关注于 cdev, 我们的设备与内核接口的 struct cdev. 这个结构必须初始化并且如上所述添加到系统中; 处理这个任务的 scull 代码是:

static void scull_setup_cdev(struct scull_dev *dev, int index)
{
 int err, devno = MKDEV(scull_major, scull_minor + index);

 cdev_init(&dev->cdev, &scull_fops);
 dev->cdev.owner = THIS_MODULE;
 dev->cdev.ops = &scull_fops;
 err = cdev_add (&dev->cdev, devno, 1);
 /* Fail gracefully if need be */
 if (err)
 printk(KERN_NOTICE "Error %d adding scull%d", err, index);
}


因为 cdev 结构嵌在 struct scull_dev 里面, cdev_init 必须调用来进行那个结构的初始化.
阅读(1356) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~