Linux内核当中关于设备的管理

深渊向深渊呼唤
在linux内核当中,主要就是字符设备和块设备,对应的结构体就是struct cdev和struct gendisk,在内核当中是通过如下结构的两个变量bdev_map和cdev_map来进行管理的:

点击(此处)折叠或打开

    struct kobj_map {
        struct probe {
            struct probe *next;
            dev_t dev;
            unsigned long range;
            struct module *owner;
            kobj_probe_t *get;
            int (*lock)(dev_t, void *);
            void *data;
        } *probes[255];
        struct mutex *lock;
    };
它本质上就是一个带互斥量的哈希表,根据设备的主设备号%255来找到对应的槽,槽冲突使用链表的形式进行解决
dev表示设备的设备号 range表示辅设备号的范围 owner表示拥有这个设备的模块 get和kobject相关 lock与设备锁定相关 data则根据不同的map类型(字符或者块)分别指向不同的结构(cdev或者gendisk) 其中两个通用的设备结构的定义如下,其中gendisk稍微复杂一点,会涉及到分区等信息:

点击(此处)折叠或打开

    struct cdev {
        struct kobject kobj;
        struct module *owner;
        const struct file_operations *ops;
        struct list_head list;
        dev_t dev;
        unsigned int count;
    } __randomize_layout;

点击(此处)折叠或打开

    struct gendisk {
        /* major, first_minor and minors are input parameters only,
         * don't use directly. Use disk_devt() and disk_max_parts().
         */
        int major;            /* major number of driver */
        int first_minor;
        int minors; /* maximum number of minors, =1 for
                                             * disks that can't be partitioned. */

        char disk_name[DISK_NAME_LEN];    /* name of major driver */
        char *(*devnode)(struct gendisk *gd, umode_t *mode);

        unsigned int events;        /* supported events */
        unsigned int async_events;    /* async events, subset of all */

        /* Array of pointers to partitions indexed by partno.
         * Protected with matching bdev lock but stat and other
         * non-critical accesses use RCU. Always access through
         * helpers.
         */
        struct disk_part_tbl __rcu *part_tbl;// 分区表
        struct hd_struct part0;

        const struct block_device_operations *fops;
        struct request_queue *queue;
        void *private_data;

        int flags;
        struct kobject *slave_dir;

        struct timer_rand_state *random;
        atomic_t sync_io;        /* RAID */
        struct disk_events *ev;
    #ifdef CONFIG_BLK_DEV_INTEGRITY
        struct kobject integrity_kobj;
    #endif    /* CONFIG_BLK_DEV_INTEGRITY */
        int node_id;
        struct badblocks *bb;
    };
















点击(此处)折叠或打开

    struct kobj_map {
        struct probe {
            struct probe *next;
            dev_t dev;
            unsigned long range;
            struct module *owner;
            kobj_probe_t *get;
            int (*lock)(dev_t, void *);
            void *data;
        } *probes[255];
        struct mutex *lock;
    };


点击(此处)折叠或打开

    struct kobj_map {
        struct probe {
            struct probe *next;
            dev_t dev;
            unsigned long range;
            struct module *owner;
            kobj_probe_t *get;
            int (*lock)(dev_t, void *);
            void *data;
        } *probes[255];
        struct mutex *lock;
    };

栏目
文章分类