Sysfs in Linux Device Drivers: The Preferred User-Kernel Interface-Linux Device Drivers Course

Sysfs in Linux Device Drivers: The Preferred User-Kernel Interface
Free Linux device drivers course — master sysfs attributes, the kernel device model, and the one-value-per-file rule.

Sysfs, mounted at /sys, is the interface the kernel community recommends today for exposing device driver attributes to user space, and understanding it well is essential if you’re following any free Linux kernel programming course seriously. Sysfs ties directly into the kernel’s internal device model, so every entry you create is automatically organized under the correct bus, class, or device directory.

What You Will Learn
The sysfs device model Creating attribute groups The one-value-per-file rule show/store callback pattern
Prerequisites
Basic platform/character driver knowledge Understanding of kobjects (helpful, not required)
Why Sysfs Became the Preferred Interface

Unlike procfs, sysfs was purpose-built around the kernel’s unified device model, meaning every driver’s attributes appear in a predictable location such as /sys/class/<class>/<device>/. Sysfs also enforces a simple discipline: each attribute file should expose exactly one value in a human-readable format, which keeps tooling and scripting predictable across thousands of different drivers.

Sysfs Attribute Flow
User: echo 1 > /sys/.../enable → kernfs calls driver’s store() → Driver updates hardware state
Creating a Sysfs Attribute (Modern Macro Style)

Modern drivers typically use the DEVICE_ATTR family of macros rather than hand-rolling kobject attributes. Here is an original, simplified example for a device attribute called threshold:

#include <linux/device.h>

static int threshold_value = 50;

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

static ssize_t threshold_store(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
{
    int ret = kstrtoint(buf, 10, &threshold_value);
    if (ret)
        return ret;
    return count;
}

static DEVICE_ATTR_RW(threshold);

Notice the use of sysfs_emit() rather than sprintf() — this helper, introduced to standardize sysfs output, correctly respects the one-page buffer limit that sysfs enforces on every attribute file.

Registering the Attribute
static struct attribute *mydrv_attrs[] = {
    &dev_attr_threshold.attr,
    NULL,
};
ATTRIBUTE_GROUPS(mydrv);

/* attach mydrv_groups to your struct device before device_register() */
Real-World Use Cases
  • Exposing LED brightness under /sys/class/leds/.
  • Reading battery capacity from a power-supply driver.
  • Toggling a GPIO-controlled fan through a custom attribute.
  • Reporting sensor calibration offsets for tuning during bring-up.
Common Mistakes and Troubleshooting
MistakeFix
Packing multiple values into one attribute fileSplit into separate files, one value each
Using sprintf() in show()Use sysfs_emit() to respect page-size limits
Forgetting input validation in store()Always check kstrtoint()/kstrtoul() return values
Best Practices
  • Group related attributes with ATTRIBUTE_GROUPS for clean registration.
  • Keep attribute names lowercase and descriptive.
  • Never block indefinitely inside show()/store(); keep them fast.
Security Considerations

Set file permissions deliberately with DEVICE_ATTR_RO, _WO, or _RW based on who should be allowed to change the value, and always validate user-supplied strings before converting them, since a malformed or oversized write should never be able to destabilize the driver.

Summary / Key Takeaways
  • Sysfs is the kernel community’s preferred way to expose device attributes.
  • Follow the one-value-per-file rule strictly.
  • Use sysfs_emit() and DEVICE_ATTR macros for modern, clean code.
  • Sysfs entries are still not a formally stable ABI, so follow current kernel documentation.
Frequently Asked Questions

Q1. What is the one-value-per-file rule in sysfs?
It means each sysfs attribute file should expose a single, simply formatted value rather than multiple mixed fields, which keeps parsing predictable for both humans and scripts.

Q2. Why use sysfs_emit() instead of sprintf()?
sysfs_emit() is designed specifically for sysfs show() callbacks and correctly handles the fixed one-page output buffer that sysfs guarantees.

Q3. Do I need kobjects to use sysfs in a driver?
Not directly for most drivers — the device model and DEVICE_ATTR macros handle kobject details for you automatically.

Q4. Can sysfs attributes change between kernel versions?
Yes, like procfs and debugfs, sysfs is documented as an interface without a guaranteed permanent stability contract.

Q5. Where do sysfs attributes for my driver appear?
Typically under /sys/class/<class_name>/<device_name>/ or under the relevant bus directory, depending on how the device was registered.

Up Next: debugfs for Flexible Debug Interfaces
Continue to debugfs Lecture

2 Comments

Leave a Reply

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