亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 17105 | 回復: 14
打印 上一主題 下一主題

看塊設備驅動部分的筆記 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2008-06-04 16:30 |只看該作者 |倒序瀏覽
對于塊設備,首先明確幾個基本的概念:

扇區(qū)(Sectors): 通常是512 bytes.  是硬件設備傳輸數(shù)據(jù)的基本單位.

塊(Blocks):     通常是1, 2, 4, 8, .... 個扇區(qū),并且小于一個page.   是內核(VFS和文件系統(tǒng))傳送數(shù)據(jù)的基本單位.

段(Segments):   是若干相鄰的塊. 是一個內存頁或者內存頁的一部分. 一般由塊設備驅動程序來處理.

每個緩沖區(qū)與一個塊對應,相當于磁盤塊在內存中的表示.


引用ULK3中的一張圖來說明它們的關系:





對于整個塊設備驅動的層次架構,ULK3中的一張圖能夠很好的說明這些:

論壇徽章:
0
2 [報告]
發(fā)表于 2008-06-04 16:30 |只看該作者
bio

相關數(shù)據(jù)結構:

/*
* main unit of I/O for the block layer and lower layers (ie drivers and
* stacking drivers)
*/
struct bio {
        sector_t                bi_sector;
        struct bio                *bi_next;        /* request queue link */
        struct block_device        *bi_bdev;
        unsigned long                bi_flags;        /* status, command, etc */
        unsigned long                bi_rw;                /* bottom bits READ/WRITE,
                                                 * top bits priority
                                                 */

        unsigned short                bi_vcnt;        /* how many bio_vec's */
        unsigned short                bi_idx;                /* current index into bvl_vec */

        /* Number of segments in this BIO after
         * physical address coalescing is performed.
         */
        unsigned short                bi_phys_segments;

        /* Number of segments after physical and DMA remapping
         * hardware coalescing is performed.
         */
        unsigned short                bi_hw_segments;

        unsigned int                bi_size;        /* residual I/O count */

        /*
         * To keep track of the max hw size, we account for the
         * sizes of the first and last virtually mergeable segments
         * in this bio
         */
        unsigned int                bi_hw_front_size;
        unsigned int                bi_hw_back_size;

        unsigned int                bi_max_vecs;        /* max bvl_vecs we can hold */

        struct bio_vec                *bi_io_vec;        /* the actual vec list */

        bio_end_io_t                *bi_end_io;
        atomic_t                bi_cnt;                /* pin count */

        void                        *bi_private;

        bio_destructor_t        *bi_destructor;        /* destructor */
        struct bio_set                *bi_set;        /* memory pools set */
};




/*
* was unsigned short, but we might as well be ready for > 64kB I/O pages
*/
struct bio_vec {
        struct page        *bv_page;
        unsigned int        bv_len;
        unsigned int        bv_offset;
};


bio是 Generic block layer(通用塊層) 的核心數(shù)據(jù)結構。

bio中的段(segment)是由bio_vec數(shù)據(jù)結構表示的。 bio相關的段被放在bio_vec的數(shù)組中,他們的關系表示如下:




其中bio的bi_idx字段會不斷保持更新,內核中提供了宏 bio_for_each_segment 用來遍歷bio中的bio_vec

論壇徽章:
0
3 [報告]
發(fā)表于 2008-06-04 16:31 |只看該作者
gendisk

相關數(shù)據(jù)結構:

struct gendisk {
        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[32];                /* name of major driver */
        struct hd_struct **part;        /* [indexed by minor] */
        struct block_device_operations *fops;
        struct request_queue *queue;
        void *private_data;
        sector_t capacity;

        int flags;
        char devfs_name[64];                /* devfs crap */
        int number;                        /* more of the same */
        struct device *driverfs_dev;
        struct kobject kobj;

        struct timer_rand_state *random;
        int policy;

        atomic_t sync_io;                /* RAID */
        unsigned long stamp, stamp_idle;
        int in_flight;
#ifdef        CONFIG_SMP
        struct disk_stats *dkstats;
#else
        struct disk_stats dkstats;
#endif
};



struct hd_struct {
        sector_t start_sect;
        sector_t nr_sects;
        struct kobject kobj;
        unsigned reads, read_sectors, writes, write_sectors;
        int policy, partno;
};




磁盤由gendisk對象來表示。
磁盤的分區(qū)用hd_struct對象表示。

磁盤的分區(qū)是通過設備的次設備號(minor)來區(qū)分的,例如
                                                                           


                                                                           
hda1就是第一個分區(qū),hda2就是第二個分區(qū)。

gendisk的part指向分區(qū)數(shù)組的首地址,數(shù)組的下標是分區(qū)的minor索引(從1開始),即數(shù)組的第一個成員是指向minor為1的分區(qū)。

論壇徽章:
0
4 [報告]
發(fā)表于 2008-06-04 16:32 |只看該作者
request_queue

相關數(shù)據(jù)結構:

請求隊列中兩個比較重要的數(shù)據(jù)結構是: request_queue 和 request

struct request_queue
{
        /*
         * Together with queue_head for cacheline sharing
         */
        struct list_head        queue_head;
        struct request                *last_merge;
        elevator_t                *elevator;

        /*
         * the queue request freelist, one for reads and one for writes
         */
        struct request_list        rq;

        request_fn_proc                *request_fn;
        merge_request_fn        *back_merge_fn;
        merge_request_fn        *front_merge_fn;
        merge_requests_fn        *merge_requests_fn;
        make_request_fn                *make_request_fn;
        prep_rq_fn                *prep_rq_fn;
        unplug_fn                *unplug_fn;
        merge_bvec_fn                *merge_bvec_fn;
        activity_fn                *activity_fn;
        issue_flush_fn                *issue_flush_fn;
        prepare_flush_fn        *prepare_flush_fn;
        end_flush_fn                *end_flush_fn;

        /*
         * Auto-unplugging state
         */
        struct timer_list        unplug_timer;
        int                        unplug_thresh;        /* After this many requests */
        unsigned long                unplug_delay;        /* After this many jiffies */
        struct work_struct        unplug_work;

        struct backing_dev_info        backing_dev_info;

        /*
         * The queue owner gets to use this for whatever they like.
         * ll_rw_blk doesn't touch it.
         */
        void                        *queuedata;

        void                        *activity_data;

        /*
         * queue needs bounce pages for pages above this limit
         */
        unsigned long                bounce_pfn;
        unsigned int                bounce_gfp;

        /*
         * various queue flags, see QUEUE_* below
         */
        unsigned long                queue_flags;

        /*
         * protects queue structures from reentrancy. ->__queue_lock should
         * _never_ be used directly, it is queue private. always use
         * ->queue_lock.
         */
        spinlock_t                __queue_lock;
        spinlock_t                *queue_lock;

        /*
         * queue kobject
         */
        struct kobject kobj;

        /*
         * queue settings
         */
        unsigned long                nr_requests;        /* Max # of requests */
        unsigned int                nr_congestion_on;
        unsigned int                nr_congestion_off;
        unsigned int                nr_batching;

        unsigned short                max_sectors;
        unsigned short                max_hw_sectors;
        unsigned short                max_phys_segments;
        unsigned short                max_hw_segments;
        unsigned short                hardsect_size;
        unsigned int                max_segment_size;

        unsigned long                seg_boundary_mask;
        unsigned int                dma_alignment;

        struct blk_queue_tag        *queue_tags;

        atomic_t                refcnt;

        unsigned int                in_flight;

        /*
         * sg stuff
         */
        unsigned int                sg_timeout;
        unsigned int                sg_reserved_size;

        struct list_head        drain_list;

        /*
         * reserved for flush operations
         */
        struct request                *flush_rq;
        unsigned char                ordered;
};



------------------------------------------------------------------

/*
* try to put the fields that are referenced together in the same cacheline
*/
struct request {
        struct list_head queuelist; /* looking for ->queue? you must _not_
                                     * access it directly, use
                                     * blkdev_dequeue_request! */
        unsigned long flags;                /* see REQ_ bits below */

        /* Maintain bio traversal state for part by part I/O submission.
         * hard_* are block layer internals, no driver should touch them!
         */

        sector_t sector;                /* next sector to submit */
        unsigned long nr_sectors;        /* no. of sectors left to submit */
        /* no. of sectors left to submit in the current segment */
        unsigned int current_nr_sectors;

        sector_t hard_sector;                /* next sector to complete */
        unsigned long hard_nr_sectors;        /* no. of sectors left to complete */
        /* no. of sectors left to complete in the current segment */
        unsigned int hard_cur_sectors;

        struct bio *bio;
        struct bio *biotail;

        void *elevator_private;

        int rq_status;        /* should split this into a few status bits */
        struct gendisk *rq_disk;
        int errors;
        unsigned long start_time;

        /* Number of scatter-gather DMA addr+len pairs after
         * physical address coalescing is performed.
         */
        unsigned short nr_phys_segments;

        /* Number of scatter-gather addr+len pairs after
         * physical and DMA remapping hardware coalescing is performed.
         * This is the number of scatter-gather entries the driver
         * will actually have to deal with after DMA mapping is done.
         */
        unsigned short nr_hw_segments;

        int tag;
        char *buffer;

        int ref_count;
        request_queue_t *q;
        struct request_list *rl;

        struct completion *waiting;
        void *special;

        /*
         * when request is used as a packet command carrier
         */
        unsigned int cmd_len;
        unsigned char cmd[BLK_MAX_CDB];

        unsigned int data_len;
        void *data;

        unsigned int sense_len;
        void *sense;

        unsigned int timeout;

        /*
         * For Power Management requests
         */
        struct request_pm_state *pm;

        /*
         * completion callback. end_io_data should be folded in with waiting
         */
        rq_end_io_fn *end_io;
        void *end_io_data;
};




每一個對于塊設備的請求都用一個request描述符來表示.
而每個請求又包含一個或多個bio結構.

對于一個請求隊列(request_queue),其所有的request描述符形成一個雙向鏈表.


論壇徽章:
0
5 [報告]
發(fā)表于 2008-06-04 16:33 |只看該作者
block_device

相關數(shù)據(jù)結構:

struct block_device {
        dev_t                        bd_dev;  /* not a kdev_t - it's a search key */
        struct inode *                bd_inode;        /* will die */
        int                        bd_openers;
        struct semaphore        bd_sem;        /* open/close mutex */
        struct semaphore        bd_mount_sem;        /* mount mutex */
        struct list_head        bd_inodes;
        void *                        bd_holder;
        int                        bd_holders;
        struct block_device *        bd_contains;
        unsigned                bd_block_size;
        struct hd_struct *        bd_part;
        /* number of times partitions within this device have been opened. */
        unsigned                bd_part_count;
        int                        bd_invalidated;
        struct gendisk *        bd_disk;
        struct list_head        bd_list;
        struct backing_dev_info *bd_inode_backing_dev_info;
        /*
         * Private data.  You must have bd_claim'ed the block_device
         * to use this.  NOTE:  bd_claim allows an owner to claim
         * the same device multiple times, the owner must take special
         * care to not mess up bd_private for that case.
         */
        unsigned long                bd_private;
};


每一個塊設備都由一個block_device對象來表示.
這里所說的塊設備其實是指一個邏輯塊設備.
比如一個磁盤由一個block_device對象來表示,而該磁盤又分了三個分區(qū),這三個分區(qū)就又是三個邏輯塊設備.

block_device中的bd_contains字段指向與整個磁盤相關的block_device對象.
因而,如果如果block_device表示一個磁盤分區(qū),則其bd_contains指向整個磁盤的block_device對象.
如果block_device表示的是一個磁盤,則其bd_contains指向自己.

block_device中有幾個比較重要的字段:
bd_disk 指向塊設備中磁盤對應的gendisk結構.
bd_part 指向hd_struct分區(qū)描述符(如果是整個磁盤的話,bd_part為NULL)



綜合前面所有的結構,整體的結構關系如下圖所示:

論壇徽章:
0
6 [報告]
發(fā)表于 2008-06-04 16:35 |只看該作者

                              
寫了個大概.

不過關于塊設備驅動這部分內容,還有很多具體的細節(jié)問題我還沒有搞太清楚.

keep on studying.

論壇徽章:
0
7 [報告]
發(fā)表于 2008-10-29 14:42 |只看該作者
寫的不錯

論壇徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
8 [報告]
發(fā)表于 2008-10-29 15:54 |只看該作者
感謝分享,學習中……

論壇徽章:
7
丑牛
日期:2013-10-18 14:43:21技術圖書徽章
日期:2013-11-03 09:58:03辰龍
日期:2014-01-15 22:57:50午馬
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亞洲杯之伊朗
日期:2015-03-16 10:24:352015亞冠之城南
日期:2015-05-31 09:52:32
9 [報告]
發(fā)表于 2011-08-21 12:16 |只看該作者
>>這里所說的塊設備其實是指一個邏輯塊設備.

個人感覺這里思路可以改成, 一個塊設備滿足塊方式的尋址和讀寫數(shù)據(jù)即可.
至于具體的讀寫 , 可以有其自己的實現(xiàn)方式.
這就如同一個物理網卡可以有多個虛擬網卡一樣. 虛擬網卡的發(fā)送最終調用物理網卡

論壇徽章:
0
10 [報告]
發(fā)表于 2011-08-21 12:46 |只看該作者
回復 1# xpl


    bytex,你的sina博客怎么不更新了。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP