Block Device Driver Analysis

Source: Internet
Author: User
Block Device Driver Analysis
Block device driver analysis, based on sbull
Before getting started, let's first understand the core data structure of this block device:
Struct sbull_dev {
Int size;/* device size in sectors */
U8 * data;/* The data array */
Short users;/* How many users */
Short media_change;/* flag a media change? */
Spinlock_t lock;/* for mutual exclusion */
Struct request_queue * queue;/* The device Request queue */
Struct gendisk * Gd;/* The gendisk structure */
Struct timer_list timer;/* for simulated media changes */
};
In this structure, struct request_queue and struct gendisk are important members in this structure,
It is also an important structure of Block devices. Most of the descriptions in this article are based on these two structures.
I. Process:
The module driver also starts from the init function, so the analysis also starts from here.
Step 1:
Register_blkdev (sbull_major, "sbull ");
Register a block device first. The first parameter is the device number, which is dynamically allocated to Table 0, and the second parameter is the device name.
Step 2:
Devices = kmalloc (ndevices * sizeof (struct sbull_dev), gfp_kernel );
Create the core data structure of the block device, that is, the object of the block device.
.
Step 3:
Setup_device (devices + I, I );
To put it bluntly, it is to initialize the object and add it to the block layer of the system. This step is very important.
To perform the following operations:
1. initialize a spin lock.
Spin_lock_init (& Dev-> lock );
2. Allocate a request queue and use the spin lock in 1 to control access to the queue.
Dev-> queue = blk_init_queue (sbull_full_request, & Dev-> lock );
3. Allocate, initialize and install the corresponding gendisk structure.
Dev-> GD = alloc_disk (sbull_minors );
If (! Dev-> Gd ){
Printk (kern_notice "alloc_disk failure/N ");
Goto out_vfree;
}
Dev-> Gd-> major = sbull_major;
Dev-> Gd-> first_minor = which * sbull_minors;
Dev-> Gd-> fops = & sbull_ops;
Dev-> Gd-> queue = Dev-> queue;
Dev-> Gd-> private_data = dev;
Snprintf (Dev-> Gd-> disk_name, 32, "sbull % C", which + 'A ');
Set_capacity (Dev-> GD, nsectors * (hardsect_size/kernel_sector_size ));
4. At last, add_disk completes the initialization process. This step must be called at the end of the initialization, because
After add_disk, the disk operation function may be called. If the initialization is not completed, an error will occur.
Ii. Structure Analysis of block device operation struct block_device_operations:
This structure in the sbull module:
Static struct block_device_operations sbull_ops = {
. Owner = this_module,
. Open = sbull_open,
. Release = sbull_release,
. Media_changed = sbull_media_changed,
. Revalidate_disk = sbull_revalidate,
. IOCTL = sbull_ioctl
};
The open and release functions are not analyzed in detail. They have an important function: Increase the user count and
Reduce user count. Media_changed and revalidata_disk are the support for removable media, such as USB flash disks.
And so on, the plug-and-play device should implement these two functions. Media_changed is used to check whether the media is
If no value is changed, the log is returned as non-zero, and the revalidate_disk is executed after the media changes. How to contact me
Don't worry, we can mainly implement the entity of this function.
The ioctl function and ioctl function are also simplified. However, most of the actual disk devices mainly implement disk Information
Information Query.
3. Request Processing.
The core of the block device driver is the request processing part, which is the difficulty of the block device driver. Well designed, direct access
Depends on the performance of the device.
We initialize a request queue when installing the block device entity:
Dev-> queue = blk_init_queue (sbull_full_request, & Dev-> lock );
This operation binds the generated Request queue Dev-> queue to the Request function sbull_full_request in
. The request function in sbull:
Static void sbull_full_request (request_queue_t * q)
{
Struct Request * req;
Int sectors_xferred;
Struct sbull_dev * Dev = Q-> queuedata;
While (req = elv_next_request (q ))! = NULL ){
If (! Blk_fs_request (req )){
Printk (kern_notice "Skip non-Fs request/N ");
End_request (req, 0 );
Continue;
}
Sectors_xferred = sbull_xfer_request (Dev, req );
If (! End_that_request_first (req, 1, sectors_xferred )){
Blkdev_dequeue_request (req );
End_that_request_last (req );
}
}
}
Req = elv_next_request (q) gets the first unfinished request in the queue.
When running end_that_request_last or end_request, the same result is obtained because it will not be deleted.
Requests in the queue. The next request is received only after the request is completed. Sbull_xfer_request here is
Is the actual data transmission.
The actual block device request processing is much more complicated, so we need to have a better understanding of the Request structure.
Structure, queue structure, and so on. However, we will not discuss it further here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.