Understanding the Linux Device Model

Embedded linux






In this article, we explain what the linux device model is and where we can find it.

The linux device model is a collection of various data structures and helper functions which provide a unifying hierarchial view of all the buses, devices, and drivers present in the linux system.

All these buses, devices, and drivers can be accessed through a pseudo file system called sysfs, which is its own directory mounted in at /sys in the linux file system.

The sysfs directory exposes the underlying bus, device, and driver details and their relationships in the Linux device model.

If you go to the root directory and linux and type in the ls command, you should see the sys directory of the linux file system.

This is shown below.


Contents of the root directory in linux


If we now cd into the sys directory, we see its contents.

This is shown below.


Contents of the sys directory in linux


You can see that we can check various directories and see its contents.

For example, let's cd into the bus directory.

Within this directory, you can see the various buses that comprise the linux system.

These buses are shown below.


Buses in linux system


We can see the various buses above which comprise the linux system. < pid="para1">As examples, there is the pci bus, the pci_express bus, platform bus, spi bus, i2c bus, usb bus, etc.

Let's cd into the platform directory of this bus.

The contents of this platform directory, representing the platform linux bus is shown below.


Contents of the platform directory in linux


We can see that within this directory are 2 directories, devices and drivers.

Devices will give all of the platform devices that are currently loaded into the linux kernel module.

Drivers will give all of the platform drivers that are currently loaded into the linux kernel module.

The drivers_autoprobe, drivers_probe, and uevent seen in this platform directory are files that represent attributes. These can be used to get certain information about a device. For example, uevent can tell us the major and minor number of a device.

We'll look into that.

First, let's look at the devices directory within this platform directory.


Devices of the platform bus in linux


One thing to note is that I created a linux platform device driver, which created 4 platform character devices. These are named pseudo-char-device.0, pseudo-char-device.1, pseudo-char-device.2, and pseudo-char-device.3

You see that these are present in the devices directory.

Next, let's look at the drivers directory within this platform directory.


Drivers of the platform bus in linux


The platform driver that I created is called, pseudo-char-device, which can be seen in this directory.

So you see that this directory has all the drivers that are currently loaded into the linux kernel.

And you can do this for any bus.

You can find out all devices connected to the usb bus, spi bus, i2c bus, etc.

Therefore, you can get a good hierarchy of all the devices of the linux system, which is referred to as the linux device model.

The sys directory allows us to see these buses, devices, and drivers and how they're all laid out in our linux system, so that we can get a good visual and knowledge for what devices are connected to what buses.


Components of the Device Model

The linux device model consists of several data structures through where the different components of the hardware and software is managed.

So going into the components of the device model, we have the following below.

There is the device, which is of type, struct device

There is the device driver, which is of type, device_driver

There is the bus, which is of type, struct bus_type

It is important in linux to know in in the linux device model, as we saw above, that though a device is anything which can be represented by an instance of the data strcuture, struct device, a device is usually not a standalone item.

Within a hardware system, such as an embedded device, a device is connected to a bus, such as the platform bus, or I2C bus, or USB bus; therefore, a device is normally classified or seen as a platform device or an I2C device or a USB device.

So, a device is normally classified by the bus it is connected to. A device connected to the platform bus will be classified as a platform device.

So, though a device is represented by a simple instance of the type, struct device, it is inherents the parent structure of the bus it is connected to.

Let's view the struct device data type in linux which is found in the /include/linux/device.h file. This structure is shown below.


struct device data type in linux


You can see in this struct device data type, there are various fields, including the parent, bus_type, device_driver, etc.

There are pertinent to know information about the device.

But remember that a device is not a truly standalone object in linux, because devices are connected to a bus.

Therefore, we must consider the bus the device is connected to.

Thus, it is rare for devices to be represented by bare device structures; subsystems will also track additional information about the devices such as the overlying bus system the device is connected to. So devices usually do not have bare device structure representation; instead, that device structure, like kobject structures, is usually embedded within a higher-level representation of the device.

As we stated before, a device connected to the platform bus will belong to the platform subsystem of linux.

This is why when we searched for devices above within the sys directory, we first went to the bus directory and from there located devices found within this bus subsystem.

This general hierarchy is shown below, representing the linux device model programming model.


Linux device model programming hierarchy


First, you have the device, an instance of struct device, with all the device specific information.

Then, you have the parent structure, representing the bus specific information.

This is because each bus is different and, thus, interacts with devices different. The bus is the conduit of how a CPU can talk to a device. Therefore, as the conduit to get to the device, our code must be coded for that bus.

A device connected to the platform bus will belong to the platform subsystem.

Therefore, the device's parent structure will be the platform_device structure.

This structure can be found in the /include/linux/platform_device.h file.

This is shown below.


struct platform_device in linux


So this is the parent structure for any device connected to the platform bus.

Notice there is a field called struct device. It is in this field that you would specify the device itself.

And then there are other fields where you would specify additional information related specifically to the platform-specific subsystem. In this case, it would be the platform bus subsystem.

Every bus system would have its own overlying parent architecture.

This information would be specific to the bus architecture in use.

For, a USB, for instance, you would go to the /include/linux/usb.h file, and you would use the usb_device structure.

This is shown below.


struct usb_device in linux


You can see that this structure has the field, struct device dev;

This is the independent device instance that you create of the device structure.

The rest of the fields are specific to the usb subsystem, including fields such as the state, speed, descriptor, etc.

Taking another example would be the SPI bus.

This can be found in the /include/linux/spi.h file, and you would use the spi_device structure.

This is shown below.


struct spi_device in linux


You see the struct device dev field.

The rest of the fields are related to the spi bus architecture.

As another example, to create an I2C driver, you would go to the /include/linux/i2c.h, and you would use the i2c_client structure.

This is shown below.


struct i2c_client in linux


You see the struct device dev field.

The rest of the fields are related to the i2c bus architecture.

And this is true for any bus architecture including others such as pci and pci_express

So this is how the linux device model works and how we code for it when creating a certain character device based on a specific bus architecture.



Related Resources





HTML Comment Box is loading comments...