sysfs Linux Device Driver Tutorial: Exposing Device Attributes the Right Way-Linux Device Driver Training in Hyderabad

Linux Device Driver Training in Hyderabad

sysfs Linux Device Driver Tutorial: Exposing Device Attributes the Right Way

Free Linux Kernel Development Course • Free Linux Device Drivers Course

What You Will Learn

  • What sysfs is and how it relates to the Linux driver model and kobjects
  • The “one value per file” rule that makes sysfs predictable
  • How to create a device attribute with DEVICE_ATTR and sysfs_create_group
  • Why sysfs, not procfs, is the modern home for driver configuration
Prerequisites: the procfs lecture in this series, and a basic understanding of the Linux driver model (device, driver, bus).

What Is sysfs?

sysfs is a virtual filesystem, mounted at /sys, that exposes the internal kernel object hierarchy (kobjects) to user space. Every device, driver, bus, and class registered with the Linux driver model gets a directory under /sys, and each attribute of that object becomes a plain text file inside that directory. Unlike procfs, which grew organically and allowed arbitrarily formatted output, sysfs enforces a strict convention: one value per file, and ideally the file should be readable with a single cat and writable with a single echo.

sysfs Directory Layout for a Device
/sys/class/mydriver/ → mydevice0/ → brightness (rw file)

Defining a Device Attribute

The macro DEVICE_ATTR (and its variants DEVICE_ATTR_RW, DEVICE_ATTR_RO, DEVICE_ATTR_WO) wires a sysfs file to a pair of show/store callback functions. This is the standard, modern pattern used across the kernel tree today.

#include <linux/device.h>
#include <linux/sysfs.h>

static int brightness_value;

static ssize_t brightness_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
{
    return sysfs_emit(buf, "%d\n", brightness_value);
}

static ssize_t brightness_store(struct device *dev,
                                 struct device_attribute *attr,
                                 const char *buf, size_t count)
{
    int val;

    if (kstrtoint(buf, 10, &val))
        return -EINVAL;

    brightness_value = val;
    return count;
}

static DEVICE_ATTR_RW(brightness);

static struct attribute *mydriver_attrs[] = {
    &dev_attr_brightness.attr,
    NULL,
};

ATTRIBUTE_GROUPS(mydriver);

Notice the use of sysfs_emit() instead of sprintf() for the show function. This is the current recommended helper; it guarantees the output never overruns the fixed PAGE_SIZE buffer sysfs hands you, something older tutorials using raw sprintf did not protect against.

Attaching the Attribute Group to a Device

Once you have an attribute group, the cleanest way to attach it in a modern driver is through the dev_groups field of the device’s class, so the sysfs files are created and removed automatically as the device is added and removed:

static struct class mydriver_class = {
    .name = "mydriver",
    .dev_groups = mydriver_groups,
};

This avoids the older pattern of manually calling sysfs_create_group() in probe and sysfs_remove_group() in remove, though that manual approach is still valid and you will see it in plenty of in-tree drivers.

Common Mistakes

  • Packing multiple unrelated values into a single sysfs file, which breaks the one-value-per-file convention and makes scripting painful.
  • Using sprintf() in a show callback instead of sysfs_emit(), risking a buffer overrun on unusually long output.
  • Forgetting that store callbacks receive a buffer that is not guaranteed to be null-terminated in every kernel version, which is why kstrtoint() style parsers are preferred over raw string functions.
  • Granting write permission on attributes that can destabilize hardware without any validation of the incoming value.

sysfs vs procfs at a Glance

Aspect procfs sysfs
ConventionFree-form text, any formatOne value per file
Tied to driver modelNoYes, via kobjects
Recommended for new driversNoYes

FAQ

Q1: Why is sysfs preferred over procfs for drivers?

Because it is tied directly to the driver model, follows a strict one-value-per-file convention, and is the interface upstream kernel maintainers expect for device attributes.

Q2: What does sysfs_emit do differently from sprintf?

It writes safely within the fixed PAGE_SIZE buffer sysfs provides, preventing overruns that raw sprintf usage could cause.

Q3: Can a sysfs file hold multiple values?

Technically yes, but it goes against convention. Split into multiple attribute files whenever possible.

Q4: What is an attribute group used for?

It bundles several device attributes together so they can be created and removed as one unit, typically tied to a device’s lifecycle.

Q5: Is sysfs available on embedded boards with a minimal kernel config?

Yes, as long as CONFIG_SYSFS is enabled, which it almost always is since much of the driver model depends on it.

sysfs tutorial device attribute linux driver free linux device drivers course free embedded systems course

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *