How to Create a Custom Attribute for a Kobject in Linux

Embedded linux






In this article, we show how to create a custom attribute for a kobject in linux.

So, as a recap, a kobject is the building block for the linux hierarchy system. Each kobject represents each of the devices found in a linux system.

If you are adding a new device to a linux system, usually with its associated device driver, you can create a custom attribute for that device.

An attribute is any given information about a device.

Attributes may include the device name, the device number, etc.

If you are dealing with a standard or custom device, you may want to create a custom attribute.

For example, if a device has a specific serial number, you may create a custom attribute that contains this serial number.

Another example, is if you are dealing with various temperature sensors, you may create a custom attribute displaying the unit temperature the sensor uses such as celsius, fahrenheit, or kelvin.

Custom attributes are just that- you can create anything for the device that gives it information that you want known about the device.

If you want to get an idea of standard attributes for an kobject, read the article, kobject attributes in linux or how to read kobject attributes in linux

So let's now go back into custom attributes.

So how do we create custom attributes for a kobject in linux?

The first thing is, we use the attribute structure in linux, which can be found at, /linux/include/linux/sysfs.h

This structure is shown below.


struct attribute in linux


So this attribute has 2 very important fields- the name field and the mode field.

The name field represents the name of the custom attribute.

For example, if the custom attribute represents the serial number of the device, you may give this a name of serialnumber.

If the custom attribute represents the unit measurement of a temperature sensor, you may give this a name of unitmeasurement.

So the name we define here.

The next important field is the mode field.

The mode field represents the permissions of access to this custom attribute.

Do you want the field to be able to be read by all? Do you want to grant write permissions to certain users such as the owner? Is this a readonly field or can a user such as the owner also update it and write a new value to it?

The mode field determines the permission for an individual kobject attribute.

Linux provides us with macros that we can use in the mode field of this attribute structure to define the access mode of the kobject.

These macros include S_IRUGO, S_IRUSR, and S_WSUR.

The most common modes of a kobject attribute are S_IRUGO (world read-only), S_IRUSR (owner read-only), and S_IRUGO | S_IWSUR (world read and only owner write).

Again, we just specify this within the mode field of the attribute structure.

So that takes care of the name and mode fields of the struct attribute.

Next we use various APIs in order to create the sysfs files (which is what kobject attributes are- files) in the sys directory that gives us some type of information related to the device.

These apis are all located in the /linux/include/linux/sysfs.h

The first API is the sysfs_create_file function, whicch creates the file of the kobject attribute.

This is shown below.


sysfs_create_files function in linux


Looking at the parameters for this function lets us see that we must only specify the address for the kobjecdt and the address for the structure attribute that we are dealing with.

Running this function will then create the file, which should then appear in the sys directory under the given kobject.

Other functions in this file are also useful, such as if we want to remove a given file (kobject attribute) from the directory, we can use the sysfs_remove_file function.

This is shown below.


sysfs_remove_files function in linux


This takes in the same parameters as the sysfs_create_files function and can be used to delete a given attribute from a kobject's directory.

We can use the sys_chmod_file function to change the access permissions to the kobject attribute.

This is shown below.


sysfs_chmod_file function in linux


This allows us to change permissions on a file already in the kobject directory.

And there are other helper functions as well such as to create groups.

So the next important thing is the struct device_attribute.

This attribute is found in the /linux/include/linux/device.h file.

This function is shown below.


struct device_attribute in linux


So you may be wondering, why do we need this?

Let's think about it, what is the reason we create attributes for kobjects?

We create kobject attributes to be able to read some information about the kobject or write a new value to an attribute.

Therefore, we need file I/O operations to able to read and write to the kobject attribute.

So we must provide read and write methods so that a user can read the value of the attribute or write a new value to an attribute.

The struct attribute only provides a way for us to speicfy the name of an attribute and its access mode (its permissions).

There is no place to add the read and write methods for the attribute.

However, with struct device_attribute, we have this now added write and read capability.

They're referred to as show and store methods, as you can see.

show refers to the read operation.

store refers to the write operation.

Also notice that the struct attribute that we created before goes into this new structure, along with the read and write file operations.

So now we have everything.

One thing worth noting is that there are, in the device.h file, device attribute variables, which we can use to make creating custom attributes easier.

Below are the definitions for various device attribute variables.


Device attribute variables in linux


The first definition is probably the most important.

The DEVICE_ATTR variable allows us to create a new custom attribute for a device with a single line of code.

You can see that this variable takes in 4 parameters- name, mode, show, and store.

The name is the name of the attribute.

The mode defines the type of access to the attribute. Readonly means the value can only be read and not altered. Write privileges means that the attribute value can be overridden.

The show method defines the function which allows for the value to be displayed to the user. This function must be defined elsewhere in code.

The store method defines the function which allows for the value to be altered. This function must be defined elsewhere in code.

So let's say that we want to create 2 attributes, unitsize and serialnumber.

unitsize represents the size that a certain device has to write to. We will make it so that this value can be read from or written to.

serialnumber represents the serialnumber of a device. This value can only be read from but not altered, as it is a fixed value that doesn't change.

In our code, using the DEVICE_ATTR variable, the lines of code would be the following as shown below.





So within our code, we specify 4 values for the DEVICE_ATTR variable.

Again, these are the attribute name, mode, show, and store functions.

If the attribute doesn't have a store function, because it doesn't have write mode functionality, this is left with a NULL value, as can be seen for the second attribute.

So let's look at the first attribute now, which has the line of code, static DEVICE_ATTR(unitsize,S_IRUGO|S_IWUSR,unitsize_show,unitsize_store);

unitsize represents the size that the device can use. This variable must be defined elsewhere in code to represent that size.

S_IRUGO|S_IWUSR represents that this device can be read from by any user and written to by the owner.

unitsize_show is the function which defines the read function for this attribute, so that a user can see its value.

unitsize_store is the function which defines the write function for this attribute, so that a user can overwrite its current value.

The second custom attribute, serialnumber, is similar, but has a different mode and has no store function because it doesn't allow for altering the attribute value.

The mode, S_IRUGO, only allows for read only access to the attribute value.

The serialnumber_show is the function which defines the read functionality for this attribute.

As the serialnumber attribute cannot be written over, the store value is set to NULL.

That shows how we can set up our custom attribute definitions.

The next thing we need to do is to define the variables and functions within these DEVICE_ATTR statements.

After the variables are defined, we have 2 show functions and 1 store function.

These are shown below.





We don't get into the actual code now because those depend on other code previously written, but you can get the idea here how the show and store methods work for these new custom attributes of the device.

One last thing that we need to do is actually create the attribute files within the device directory.

This is done with the sysfs_create_files() function, which we showed earlier in this article.

This is the function which will actually create the attributes which we will be visible within the device directory.

The code to do this is shown below.





This code will create both attributes in a single function.

You will understand this better when you see the full code, which will be posted here soon.

So this is how to create a custom attribute for a kobject in linux.



Related Resources





HTML Comment Box is loading comments...