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.
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.
User: echo 1 > /sys/.../enable |
→ | kernfs calls driver’s store() |
→ | Driver updates hardware state |
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.
static struct attribute *mydrv_attrs[] = {
&dev_attr_threshold.attr,
NULL,
};
ATTRIBUTE_GROUPS(mydrv);
/* attach mydrv_groups to your struct device before device_register() */
- 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.
| Mistake | Fix |
|---|---|
| Packing multiple values into one attribute file | Split 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 |
- Group related attributes with
ATTRIBUTE_GROUPSfor clean registration. - Keep attribute names lowercase and descriptive.
- Never block indefinitely inside show()/store(); keep them fast.
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.
- 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.
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.

2 Comments