Friday 20 July 2018

Character Device Driver Major Number and Minor Number

One of the basic features of the Linux kernel is that it abstracts the handling of devices. All hardware devices look like regular files; they can be opened, closed, read and written using the same, standard, system calls that are used to manipulate files. To Linux, everything is a file. To write to the hard disk, you write to a file. To read from the keyboard is to read from a file. To store backups on a tape device is to write to a file.


So device driver also like file. Driver will create the special file for every hardware devices. We can communicate to the hardware using those special files (device file).If you want to create the special file, we should know about the Major number and minor number in device driver.


Major number

Traditionally, the major number identifies the driver associated with the device. A major number can also be shared by multiple device drivers. See /proc/devices to find out how major numbers are assigned on a running Linux instance.
cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
Block devices:
1 ramdisk
259 blkext
These numbers are major numbers








Minor Number

Major number is identify the corresponding driver. Many devices may use same major number. So we need to assign the number to each devices which is using same major number. So this is the minor number.

Allocating Major and Minor Number

We can allocating the major and minor numbers by two ways.
  1. Statically allocating
  2. Dynamically Allocating
Statically allocating
If you want to set the particular major number to your driver, you can use this method.
int register_chrdev_region(dev_t first, unsigned int count, char *name);
Here, first is the beginning device number of the range you would like to allocate.
count is the total number of contiguous device numbers you are requesting. Note that, if count is large, the range you request could spill over to the next major number; but everything will still work properly as long as the number range you request is available.
name is the name of the device that should be associated with this number range; it will appear in /proc/devices and sysfs.
The return value from register_chrdev_region will be 0 if the allocation was successfully performed. In case of error, a negative error code will be returned.

The dev_t type (defined in ) is used to hold device numbers—both the major and minor parts. dev_t is a 32-bit quantity with 12 bits set aside for the major number and 20 for the minor number.
If you want to create the dev_t structure variable for your major and minor number, please use below function.
MKDEV(int major, int minor);
If you want to get your major number and minor number from dev_t, use below method.
MAJOR(dev_t dev);
MINOR(dev_t dev);  it will return that major/minor number of your driver.
Example:
dev_t dev = MKDEV(235, 0);
 
register_chrdev_region(dev, 1, "Embetronicx_Dev");


Dynamically Allocating

If we dont want fixed major and minor number please use this method. This method will allocate the major number dynamically to your driver which is available.
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
dev is an output-only parameter that will, on successful completion, hold the first number in your allocated range.
firstminor should be the requested first minor number to use; it is usually 0.
count is the total number of contiguous device numbers you are requesting.
name is the name of the device that should be associated with this number range; it will appear in /proc/devices and sysfs.

Difference between static and dynamic method

Static method is only really useful if you know in advance which major number you want to start with. With Static method , you tell the kernel what device numbers you want (the start major/minor number and count) and it either gives them to you or not (depending on availability).
With Dynamic method, you tell the kernel how many device numbers you need (the starting minor number and count) and it will find a starting major number for you, if one is available, of course.

Unregister the Major and Minor Number

Regardless of how you allocate your device numbers, you should free them when they are no longer in use. Device numbers are freed with:
void unregister_chrdev_region(dev_t first, unsigned int count);

Program for Statically Allocating Major Number

In this program, I’m assigning 235 as a major number.

  • Build the driver by using Makefile (sudo make)
  • Load the driver using sudo insmod
  • Check the major number using cat /proc/devices
linux@embetronicx-VirtualBox::/home/driver/driver$ cat /proc/devices | grep "Embetronicx_Dev"
235 Embetronicx_Dev
  • Unload the driver using sudo rmmod

Program for Dynamically Allocating Major Number

This program will allocate major number dynamically.

  • Build the driver by using Makefile (sudo make)
  • Load the driver using sudo insmod
  • Check the major number using cat /proc/devices
linux@embetronicx-VirtualBox::/home/driver/driver$ cat /proc/devices | grep "Embetronicx_Dev"
243 Embetronicx_Dev
  • Unload the driver using sudo rmmod
This function allocates major number of 243 for this driver.




No comments:

Post a Comment