Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


❑ Characteristic data such as sector and block size or device capacity.
❑ Thegeneric hard diskabstractiongenhdthat is available for each device and that stores both parti-
tioning data and pointers to low-level operations.

Each block device must provide aprobefunction that is registered with the kernel either directly by
means ofregister_blkdev_rangeor indirectly via thegendiskobject discussed below usingadd_disk.
The function is invoked by the filesystem code to find the matchinggendiskobject.

Read and write requests to block devices do not immediately cause the corresponding operations
to be executed. Instead, they are collected and transferred to the device later in a kind of concerted
action. For this reason, no specific functions to perform the read and write operations are held in the
file_operationsstructure for the corresponding device files. Instead, they contain generic versions
such asgeneric_read_fileandgeneric_write_file, which are discussed in Chapter 8.

What is remarkable is thatexclusivelygeneric functions are used — a distinctive feature of block devices.
In character devices these functions are represented by driver-specific versions. All hardware-specific
details are handled when requests are executed; all other functions work with an abstracted queue and
receive their results from buffers and caches that do not interact with the underlying device until it
is absolutely necessary. The path from thereadorwritesystem call to actual communication with a
peripheral device is therefore long and complex.

6.5.2 Data Structures


Until now, I have only gently touched the data structures required to represent block devices within the
kernel. Now I am going to dissect them in detail.

Block Devices


The core properties of a block device are represented by — the name says it all —struct block_device.
Let us discuss this structure first and afterward examine how it fits into a network with various other
structures.

<fs.h>
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 list_head bd_inodes;
void * bd_holder;
...
struct block_device * bd_contains;
unsigned bd_block_size;
struct hd_struct * bd_part;

unsigned bd_part_count;
int bd_invalidated;
struct gendisk * bd_disk;
struct list_head bd_list;
...
unsigned long bd_private;
};
Free download pdf