Linux Device Driver Tutorial Part 32 – Misc Device Driver

This is the Series on Linux Device Driver. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Linux Device Driver Tutorial Part 32 – Misc device driver in the Linux Device Driver.

Misc Device Driver

Prerequisites

In this misc device driver tutorial, we just used the below tutorial as a reference. Please go through the below tutorial before we began.

Introduction – Misc Device Driver

Misc driver is the miscellaneous driver for miscellaneous devices. We can say that misc drivers are special and simple character drivers. You can write this misc driver when you cannot classify your peripheral. This means, if you don’t want to use the major number, then you can write this misc driver. And also if you want to write a simple driver, then you can choose a misc driver instead of choosing a character driver.

So, you cannot choose the major number yourself when you write the misc driver. The default major number of all the misc drivers is 10. But you can choose your minor numbers between 1 to 255. It has all the file operation calls like open, read, write, close, and IOCTL. This will create the device file under /dev/{your_misc_file}It is almost like the character driver. Isn’t it? Then why the hell we are using the misc devices, and what is different between misc drivers and character drivers? Let’s continue reading.

Difference between character driver and misc driver

  • In misc driver, the major number will be 10 and the minor number is user convenient. Whereas, in character drivers, the user can select their own major and minor number if it is available.
  • The device node or device file will be automatically generated in misc drivers. Whereas, in character drivers, the user has to create the device node or device file using cdev_init, cdev_add, class_create, and device_create.

Uses of Misc drivers

  • If you write character drivers for simple devices, you have to create a major number as well. In such a case, the kernel has to keep that details in the static table. Which means, you end up wasting the RAM for simple devices. If you write multiple character drivers for multiple simple devices, then the RAM wastage also increases. To avoid this you can use the misc driver. Because, in the misc driver, you don’t need to specify the major number since it has a fixed major number which is 10.
  • If you use misc drivers, it will automatically create the device file compare to the character driver.

I hope you are okay to go to programming now.

Misc Device Driver API

In order to create misc drivers, we need to use miscdevice structure, file operations. After that, we need to register the device. Once we have done with the operation, then we can unregister the device. The following APIs are used to create and delete the misc device. You need to insert the header file include<linux/miscdevice.h>.

Misc device structure

Character drivers have cdevstructure to know the driver’s functions and other calls. Like that, the misc driver also has a separate structure to maintain the details. The structure as follows,

Where,

<minor>: You can assign your custom minor number to this. If you pass MISC_DYNAMIC_MINOR to this variable, then the misc driver will automatically generate the minor number and assign it to this variable. Every misc driver needs to have a different minor number since this is the only link between the device file and the driver. Recommended is a dynamic method to allocate the minor number instead of assigning the same minor number to the different misc devices. If you want to select your own minor number then check for the used minor number of all misc devices using ls -l /dev/then you can hardcode your minor number if it is available.

<name>: you can assign the name of the misc driver. The device file will be created in this name and displayed under the /dev directory.

<fops>: This is the pointer to the file operations. This is the same file operation in character drivers.

<next> and <prev>: These are used to manage the circular linked list of misc drivers.

Once you loaded the misc driver, then you can see the major and minor number of your misc device driver using ls -l /dev/{misc_driver_name}. Please see the example below.

Register the misc device

This API is used to register the misc device with the kernel.

int misc_register(struct miscdevice * misc)

where,

<misc>: device structure to be registered

return: A zero is returned on success and a negative errno code for failure.

You have to call this function in init function. The structure passed is linked into the kernel and may not be destroyed until it has been unregistered.

This one function will avoid the below functions used in the character device driver while registering the device.

  1. alloc_chrdev_region(); – used for the major and minor number
  2. cdev_init(); – used to initialize cdev
  3. cdev_add(); – used to  add the cdev structure to the device
  4. class_create();  – used to create a class
  5. device_create();  – used to create a device

That’s why we are telling this is the simple method.

Example

Now the __init function looks simple know compared to character device drivers? 😆 Let’s see the unregister function.

Unregister the misc device

This API is used to un-register the misc device with the kernel.

misc_deregister(struct miscdevice * misc)

where,

<misc>: device structure to be un-registered

Unregister a miscellaneous device that was previously successfully registered with misc_register(). This has to be called in __exit function.

This one function will avoid the below functions used in the character device driver while un-registering the device.

  1. cdev_del(); – used to delete cdev
  2. unregister_chrdev_region();  – used to remove the major and minor number
  3. device_destroy();  – used to delete the device
  4. class_destroy(); – used to delete the class

Example

Woohoo. That’s all. Just two APIs are needed to create the misc driver. Is it really simple compared to the character driver? Let’s jump to programing.

Example Programming

Here I have added a dummy misc device driver snippet. In this driver code, we can do all open, read, write, close operations. Just go through the code.

Driver Source Code

[Get the source code from the GitHub]

Makefile

Execution

  • Build the driver by using Makefile (sudo make)
  • Load the driver using sudo insmod misc_driver.ko
  • To check the major and minor number, use ls -l /dev/simple_etx_misc

  • Here, 10 is the major number and 53 is the minor number.
  • Now we will see write and read. Enter sudo su and enter your password if it asks to give permission.
  • Do echo 1 > /dev/simple_etx_misc

Echo will open the driver and write 1 into the driver and finally close the driver. So if I do echo to our driver, it should call the open, write, and release (close) functions. Just check it out.

  • Now Check using dmesg

  • That’s cool. Now we will verify the read function. Do cat > /dev/simple_etx_misc

Cat command will open the driver, read the driver, and close the driver. So if I do cat to our driver, it should call the open, read, and release (close) functions. Just check.

  • Now Check using dmesg

  • Unload the driver using sudo rmmod misc_driver

Instead of doing echo and cat command in the terminal you can also use open(), read(), write(), close() system calls from user-space applications.

This is just a dummy misc driver. But you can implement your own logic in read, write, and IOCTL too like we did in our previous Linux device driver tutorials.

In our next tutorial, we will see the USB device drivers in Linux.

0 0 vote
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Kathir
Kathir
May 11, 2020 11:00 AM

Thanks for this tutorial. I was waiting for this for a long time. Thank you embetronicx.

1
0
Would love your thoughts, please comment.x
()
x
%d bloggers like this: