Examples of Linux block device drivers

Source: Internet
Author: User

The first two blog has been basically familiar with the structure of the block equipment, here to summarize the ldd3 mentioned in some of the block device drive examples;


1, registration: Register a block device driver to the kernel , is actually using the main device number to tell the kernel this representative block device driver

        Sbull_major  =  Register_blkdev (sbull_major, "sbull");        if (0 >=  sbull_major) {            printk (kern_warning "Sbull:   unable  to  get  major  Number!\n ");            return  -ebusy;        }


2. Define the structure of the device:

struct sbull_dev{     int size;//sector unit, device size     U8  *data;//data array short users;//     number of users short     Media_ Change Media change identification     spinlock_t lock;//For Mutex     struct request_queue  *queue;//device request queue     struct Gendisk  *gd; Gendisk structure     struct timer_list time;//used to simulate media changes};


3. Initialize the structure of the device:

memset (Dev, 0, sizeof (struct sbull_dev)); Dev->size  = nsectors * hardsect_size; Dev->data  = Vmalloc (dev->size); if (dev->data = = NULL) {     PRINTK (kern_notice "Vmalloc failure.\n");     Return } spin_lock_init (&dev->lock);//Initialize the spin lock for the next queue assignment

4. Create the request queue for the device:

Dev->queue = Blk_init_queue (Sbull_request, &dev->lock);


5, the allocation, initialization and installation of 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, +, "sbull%c", which + ' a '); Set_capacity (DEV->GD, nsectors* (hardsect_size/kernel_sector_size));//using Kernel_sector_size Local constants, Perform a kernel 512-byte sector to the actual sector size conversion  Add_disk (DEV->GD);

Sbull_minors is the number of secondary device numbers supported Per device, one device named Sbulla, and the second sbullb. User space can add partitions, and a third partition on the second device may be/dev/sbullb3.


6. Set the sector size supported by the queue

Notifies the kernel device of the supported sector size, and the hardware sector size is placed in the queue as a parameter, rather than in Gendisk. Call the following function immediately after assigning the queue:

Blk_queue_hardsect_size (Dev->queue, hardset_size);

Once the above function is called, the kernel will use the set hardware sector size for our device, all the I/O requests are located at the beginning of the hardware sector, and each request size will be an integer multiple of the sector size. Remember: The kernel always thinks that the sector size is 512 bytes, so you must convert all the number of sectors.

7. Implement the Operation function:

To open the device function:

static int Sbull_open (struct inode *inode,  struct file *filp) {     struct sbull_dev  *dev = inode->i_bdev- >bd_disk->private_data;      Del_timer_sync (&dev->timer);//Remove timer     filp->private_data = dev;     Spin_lock (&dev->lock);      if (!dev->users)         check_disk_change (Inode->i_bdev);//Check if the media in the drive changes     dev->users++;//increase user Count     Spin_unlock (&dev->lock);     return 0; }

To turn off the device function:

static int sbull_release (struct inode *inode,  struct file *filp) {     struct sbull_dev  *dev = inode->i_bdev- >bd_disk->private_data;      Spin_lock (&dev->lock);     dev->users--;      if (!dev->users) {         dev->timer.expires = jiffies + invalidate_delay;//Set timer         add_timer (&dev-> timer);     }      Spin_unlock (&dev->lock);     return 0; }

Other functions are implemented as well, similar to character device drivers. Here is not to write, next look at the core, for a block device driver is the core part of the request, almost all the center of gravity in the request function;


8. Handling Request operation

Dev->queue = Blk_queue_init (&sbull_request, &dev->lock);  static void Sbull_request (request_queue _t *q)  {     struct request *req;      while (req = Elv_next_ Request (q)) = null) {//Gets the first outstanding request in the queue, and returns null if none. Do not delete this request after processing          struct Sbull_dev *dev = Req->rq_disk->private_data ;         if (! blk_fs_request (req)) {//Determine if a file system request is not a block device request               PRINTK (kern_notice "Skip non-fs  request.\ n ");             end_request (req, 0);              continue;         } The//sbull_transfer () function is a real processing block device request function          Sbull_transfer (d EV, Req->sector, req->current_nr_sectors, req->buffer, Rq_data_dir (req));         end_request (req, 1);     } }  void end_request (struct request* req, int succeeded),  //sector The index number of the start sector, Refers to a 512-byte sector, if it is a 2048-byte sector, then SECTOR/4//Nsect indicates how many sectors to pass, buffer data cache address pointer; Write indicates the direction of data passing, that is,:read/write;  static void Sbull_transfer (struct Sbull_dev *dev, unsigned long sector, unsigned long nsect, char *buffer, int write) &nbsp ; {     unsigned long offset = sector*kernel_sector_size;     unsigned long Nbytes = nsect*kernel_sector_size;      if (offset + nbytes) > Dev->size) {          PRINTK (kern_notice "beyond-end  write (%ld%ld) \ n", offset, nbytes);  & nbsp;       return;    }      if ( Write)          memcpy (dev->data + offset, bUffer, nbytes);     else         memcpy (buffer, dev- >data + offset, nbytes);  }

Reprint Address: Example of Linux block device driver

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Examples of Linux block device drivers

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.