Linux Device Driver Programming Lecture 29- Dynamically allocating char device numbers

  • Post author:
  • Post category:Blog

 

Dynamically allocating char device numbers

 

 

In this article, let’s understand how to use alloc_chrdev_region() API to dynamically create and register a range of character device numbers.

Purpose of alloc_chrdev_region():

alloc_chrdev_region() is a kernel API used to dynamically create and register a range of character device numbers.

Dynamically register a range of char device numbers
Figure 1. Dynamically register a range of char device numbers

 

This kernel API requires four input arguments.

Input Parameters:

  • dev_t *dev:

This is the first one, a pointer. This is an output parameter for the first assign number.

Here, at this place, you should mention a pointer where the first device number will be updated by the alloc_chrdev_region function. As you can see here, a this pointer is of type dev_t. That is actually a typedef data type for unsigned int 32 data type.

All you need to do is you just create a variable of type dev_t and then mention the pointer here, where the alloc_chrdev_region() will update the first assign number. 

  • unsigned baseminor

The second argument here is unsigned baseminor. Here, you mention the first of the requested range of minor numbers. You can request n number of minor numbers for a major number. The first minor number you can mention here. This argument usually 0. Most of the time, it is 0. 

  • unsigned count 

In the unsigned count argument, you can mention a number of minor numbers required.

  • const char *name

You can give a name for a range of device numbers. Remember that this is not a device file name. This is just a name you give for the range of a device numbers.

 

How to use this? 

Example Usage:

int alloc_chardev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *nam);

/*Device number creation*/

dev_t device_number;

alloc_chrdev_region(&device_number, 0, 7, "eeprom");

Example

First, you have to create a variable device_number of type dev_t. I’ll explain what exactly is dev_t and what’s the format of that? This is just a 32-bit data type like a  uint_32.

In the alloc_chrdev_region(), the first parameter should be the address of this variable.

Here(&device_number), the first device_number will be updated by the alloc_chrdev_region. And here, the second parameter is a baseminor. The first minor number you have to select. Typically this is 0.

Major and Minor Numbers:

  • The major number is dynamically allocated by alloc_chrdev_region().
  • Major numbers are typically generated dynamically to ensure uniqueness.
  • The first minor number is specified by the baseminor argument.
  • The combination of the major and minor numbers forms the device number, represented by the dev_t type.

And here is the number of minor numbers requested, let’s say 7. When you do this much, seven device_numbers will be created.  Let’s say 127:0, 127:1,127:2, all the way to 127:6. The total Count is seven, as shown in Figure 2.

Figure 3. Device number creation- alloc_chrdev_region
Figure 2. Device number creation

 

0 is a first minor as per your request. It started from 0 because you requested that in this field.

After that, 127 is a major number, which is allocated dynamically by the alloc_chrdev_region(). This is allocated dynamically. I mean, a free major number will be used. So, never get this a major number. We cannot guess that that is generated dynamically by the alloc_chrdev_region. And the first device_number is updated in this device number variable.

And for this device_number, you can give one name, and that name is this one in (double quote) “ “. Again I’m telling you this is not a device filename remember that. This is just a name you give to identify this device_number range. 

 

Now, what does it return?

The return type is int.

Let’s not worry about what it returns again. We’ll explore that later when we do Error handling.

For the time being, let’s assume that, so the call will always be successful. Later will investigate what exactly is a return type. Based to the return type, we have to take care of error handling that I will cover in later articles. We are not worried about error handling for a time being.

 

Figure 4. Device number representation- alloc_chrdev_region
Figure 3. Device number representation

 

Now, let’s explore the device_number  representation(explained in Figure 3) by using an alias name that is dev_t. That’s a typedef of uint32. You know that the device_number is a combination of major and minor numbers.

In Linux kernel, dev_t type is used to represent the device number. It is an entity of 32bits. Out of 32 bits, 12 bits to store major number and the remaining 20 bits to store minor number. You can use the below macros to extract major and minor parts of dev_t type variable.

Let’s say you have a variable device_number of type dev_t and if you want to extract the minor and major number out of this variable, just use these macros MINOR(device_number) and MAJOR(device_number).

These macros are mentioned in kdev_t.h in the linux kernel. And if you have major and minor numbers, use the below macro to turn them into dev_t type device  Number. You can use  MKDEV(int major, int minor)

So, just pass the argument major and minor, and it will give you a device number of type dev_t. A device number is represented by the data type dev_t. 

With that note, I would like to end this article; from the next article onwards, let’s get started with the coding of our first character driver, that is pseudo character driver

 

Get Full course on Linux Device Driver Here

FastBit Embedded Brain Academy Courses

Click here:  https://fastbitlab.com/course1

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.