Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


The way entries are organized is quite similar to the techniques employed forstruct kobj_mapabove.
nextlinks all elements on the same hash line (major_to_indexcomputes the hash position given a major
number). You will have guessed thatmajorspecifies the major number, whilebaseminoris the smallest
minor number in a consecutive range ofminorctminor numbers.nameprovides an identifier for the
device. Usually, this name is chosen similar to the name of the device special file used for the device, but
this is no strict requirement.fopspoints to thefile_operationsassociated with the device, andcdev
provides a link withstruct cdev, which is discussed in Section 6.4.1.

Registration Procedures


Now consider how block and character devices are registered.

Character Devices


Registering a block device in the kernel requires two steps:

❑ Register or allocate a range of device numbers. If the driver wants to use a specified range of
device numbers,register_chrdev_regionmust be employed, whilealloc_chrdev_regionlets
the kernel choose an apt range. The prototypes are as follows:
<fs.h>
int register_chrdev_region(dev_t from, unsigned count, const char *name)
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name);

When a new range is allocated withalloc_chrdev_region, the smallest minor number and
the size of the desired range have to be specified inbaseminorandcount. The selected major
number is returned indev.Notethatstruct cdevisnotrequired to register or allocate device
numbers.
❑ After a device number range has been obtained, the device needs to be activated by adding
it to the character device database. This requires initializing an instance ofstruct cdevwith
cdev_init, followed by a call tocdev_add. The prototypes of the functions are defined as
follows:
<cdev.h>
void cdev_init(struct cdev *cdev, const struct file_operations *fops);
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
fopsincdev_initcontains pointers to the operations that handle the actual communication
with the device.countincdev_adddenotes how many minors the device provides.
Observe, for instance, how the FireWire video driver activates a character device (the driver has
already registered the major numberIEEE1394_VIDEO1394_DEVwith 16 minor numbers before).
drivers/ieee1394/video1394.c
static struct cdev video1394_cdev;

cdev_init(&video1394_cdev, &video1394_fops);
...
ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16);

Aftercdev_addreturns successfully, the device is alive and active.
Free download pdf