Download presentation
Presentation is loading. Please wait.
1
Introduction to Linux Device Drivers
Class 5: Linux and Block Device Drivers Aug 8, 2014 Khem Raj
2
Introduction Block Device Drivers are like character drivers
They use device files MAJOR/MINOR numbers Fileops Register devices
3
Introduction Differences w.r.t. character drivers
Work with block of data instead of byte-oriented Use I/O instead of VFS Contains file systems Can interact with caching mechanism, character drivers interact with h/w directly Have random-access How does block device drivers differ from character drivers ?
4
Block Device Layer Application Virtual File system layer
User Space Read Write Open Kernel Space Hardware space Application Virtual File system layer File systems, ext4, btrfs etc Buffer Caches Block layer Disk Device
5
Block Layer Applications use block devices Always goes through VFS
Through filesystems Directly to device files (/dev/…) Always goes through VFS Buffer cache speeds up accesses
6
Block Layer Kernel Space File I/O hardware space Buffer Caches
Block Driver Block Driver I/O schedulers Why do we use buffer cache ? Block Driver
7
Block layer Responsible for I/O scheduling
Uses I/O schedulers to Optimize disk access Batch writes Block device driver handles requests Irrespective of request passing or not through I/O scheduler I/O schedule used for Hard disks Not used for Memory based devices, RAID
8
I/O Schedulers Noop - block/noop-iosched.c
Anticipatory – block/as-iosched.c Deadline - block/deadline- iosched.c Completely Fair Scheduler (default) - block/cfq-iosched.c
9
Block Drivers Registering Unregistering
int register_blkdev(unsigned int major, const char *name); major dynamically selected upon being passed 0 Device appears under /proc/devices Unregistering void unregister_blkdev(unsigned int major, const char *name); See <linux/fs.h> for more
10
Block Drivers Device File operations
Provided through block_device_operations Functions open release ioctl media_changed - Returns true on media change revalidate_disk – Called if media_changed() returned true, resets device Owner See <linux/blkdev.h> for more
11
Block Drivers Device registration (gendisk structure)
struct gendisk *alloc_disk(int minors); Allocate the struct void add_disk(struct gendisk *disk) Creates Fields major - set to the major number first_minor minors - allows for partitions disk_name - shows up in /proc/partitions and sysfs, e.g., “hda”, /sys/block/hda void del_gendisk(struct gendisk *disk); Delete See <linux/genhd.h>
12
Block Drivers – Request Queues
Request Queues – Read/write implementation Block drivers don’t have read/write Used with I/O schedulers Provides Request queue for Read-write queuing Lock that goes with request queue Request function for processing the queue
13
Block Drivers – Request Queues
Initialized with struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *) Provide function to process request and lock Cleanup void blk_cleanup_queue(struct request_queue *) Request processing function void request_fn(struct request_queue *q);
14
Block Drivers – Request Queues
Request functions should get request using struct request *blk_fetch_request(struct request_queue *q); If not initiated then initiate processing Should be non-blocking Called from non process context Called after taking the spin lock of queue Functions which don’t take lock should be used/called inside this function What are request queues ?
15
Block Drivers – Processing Request
Write a function e.g. my_request(request_queue_t *q) Loops until last request call req = elv_next_request(q) to get next request To finish call end_request()
16
Example Initialization
Registers the block device using register_blkdev() Register request method Supply address of my_disk_controller_request () to blk_init_queue() blk_init_queue() returns the request_queue Set sector size and max number of sectors per transaction supported by h/w for block layer blk_queue_hardsect_size() and blk_queue_max_sectors() Call
17
Example Intialization – Prepare gendisk
Allocate and initialize gendisk struct using alloc_disk() Initialize gendisk field for address of the driver's block_device_operations Set capacity in number of sectors set_capacity() Set flags to denote if h/w is removable GENHD_FL_REMOVABLE Link gendisk with the request_queue Add disk to block I/O layer - add_disk()
18
Example Exit perform cleanup - del_gendisk( )
Drop references to the gendisk - put_disk() Unregister the driver from the request_queue - blk_cleanup_queue( ) Unregister the block device - unregister_blkdev ()
19
Example block_device_operations Open() Ioctl() media_changed()
Mounting or fsck If removable call check_disk_change() Ioctl() Device commands e.g. eject media_changed() storage media has changed or not Name some of block device operations ?
20
Example Disk Access Operations
Block I/O subsystem calls drivers request() method to process requests from request_queue Kernel holds a lock when calling driver’s request() function
21
Example my_disk_controller_request(struct request_queue *q)
Loop through requests queue Program the start sectors –outb() Check for filesystem request - blk_fs_request() READ – read sector In loop – inb() WRITE – output buffer into data registers – outb() End request reached - end_request()
22
Thanks Questions?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.