The /sys Filesystem and udev
/sys exposes the kernel's hardware device tree as a filesystem. Every device, driver binding, and hardware parameter is visible and writable. udev sits on top and automates responses to hardware events. Together they are the kernel's live hardware interface.
Series: Learning Linux from Scratch
- 1. Learning Linux from Scratch — After a Full IT Apprenticeship
- 2. What is Linux?
- 3. The Filesystem
- 4. Users and Permissions
- 5. Installing and Managing Software
- 6. Text Editors
- 7. Shell Scripting Basics
- 8. Process Management
- 9. Networking Fundamentals
- 10. SSH
- 11. systemd and Services
- 12. Disk Management
- 13. Users and Groups — In Depth
- 14. Cron and Scheduled Tasks
- 15. Firewall — iptables and ufw
- 16. Environment Variables and the Shell
- 17. Log Management
- 18. Kernel Module Management
- 19. The /proc Filesystem — In Depth
- 20. The /sys Filesystem and udev
- 21. Kernel Parameters and sysctl
- 22. Compiling and Installing a Custom Kernel
/sys is the other major virtual filesystem alongside /proc. Where /proc exposes process and kernel state, /sys exposes the hardware device tree — every device the kernel knows about, organised by how it connects to the system. It is also the primary interface for configuring hardware behaviour at runtime.
sysfs vs procfs
/proc grew organically over decades and became a mix of process info and general kernel state. /sys was introduced in Linux 2.6 to provide a cleaner, structured representation of the kernel's device model.
The key difference:
/procis mostly read-only kernel state and per-process info/sysis the live device tree with writable files for controlling hardware
The /sys structure
ls /sysblock bus class dev devices firmware fs hypervisor kernel module power
The most important directories:
| Directory | Contents |
|---|---|
/sys/devices/ | The full device tree, mirroring the physical hardware topology |
/sys/bus/ | Devices organised by bus type (pci, usb, platform, i2c, etc.) |
/sys/class/ | Devices organised by class (net, block, input, etc.) |
/sys/block/ | Block devices (disks) |
/sys/module/ | Loaded kernel modules and their parameters |
/sys/kernel/ | Kernel internals |
/sys/power/ | Power management |
Exploring hardware
Network interfaces
ls /sys/class/net/Each interface has a directory. Inside:
cat /sys/class/net/eth0/address # MAC address
cat /sys/class/net/eth0/speed # link speed in Mbps
cat /sys/class/net/eth0/operstate # up/down/unknown
cat /sys/class/net/eth0/statistics/rx_bytes # received bytes
cat /sys/class/net/eth0/statistics/tx_bytes # transmitted bytesBlock devices
ls /sys/block/cat /sys/block/sda/size # size in 512-byte sectors
cat /sys/block/sda/queue/rotational # 1 = HDD, 0 = SSD
cat /sys/block/sda/queue/scheduler # I/O schedulerCheck if a disk is an SSD:
cat /sys/block/sda/queue/rotational0 means SSD. 1 means spinning disk.
PCI devices
ls /sys/bus/pci/devices/Each device is identified by its PCI address (domain:bus:device.function). Follow symlinks to the device tree:
cat /sys/bus/pci/devices/0000:02:00.0/vendor # vendor ID (hex)
cat /sys/bus/pci/devices/0000:02:00.0/device # device ID (hex)
cat /sys/bus/pci/devices/0000:02:00.0/driver # symlink to driverCPU topology
ls /sys/devices/system/cpu/cat /sys/devices/system/cpu/cpu0/topology/physical_package_id # which socket
cat /sys/devices/system/cpu/cpu0/topology/core_id # which core
cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list # sibling HT threadsCPU frequency scaling:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # current governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq # current frequency
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governorsChange the CPU frequency governor:
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governorGovernors:
performance— always run at maximum frequencypowersave— always run at minimum frequencyondemand— scale up under load, scale down when idleschedutil— modern scheduler-based scaling (default on most kernels)
Controlling hardware via /sys
Brightness (laptops)
cat /sys/class/backlight/intel_backlight/max_brightness
echo 500 | sudo tee /sys/class/backlight/intel_backlight/brightnessLED control
ls /sys/class/leds/
echo 0 | sudo tee /sys/class/leds/input2::capslock/brightness # turn off caps lock LEDPower management
cat /sys/power/state # available sleep states: freeze mem disk
echo mem | sudo tee /sys/power/state # suspend to RAMDisk power management:
cat /sys/block/sda/device/power/control # auto or on
echo on | sudo tee /sys/block/sda/device/power/control # disable power managementDriver binding and unbinding
You can detach a device from its driver and attach it to a different one without rebooting.
Unbind a device from its current driver:
echo "0000:02:00.0" | sudo tee /sys/bus/pci/devices/0000:02:00.0/driver/unbindBind it to a new driver:
echo "0000:02:00.0" | sudo tee /sys/bus/pci/drivers/vfio-pci/bindThis is how GPU passthrough to virtual machines works — the GPU is unbound from the host driver and bound to vfio-pci.
udev
udev is the device manager for the Linux kernel. It runs in userspace and responds to kernel events (uevents) when hardware is added or removed.
When you plug in a USB device, the kernel detects it and sends a uevent. udev receives that event and applies rules to decide what to do — create a /dev entry, set permissions, load a module, run a script.
udev rules
Rules live in /etc/udev/rules.d/ (user rules) and /lib/udev/rules.d/ (system rules). Files are processed in alphanumeric order — lower numbers run first.
A rule file is named NN-description.rules where NN is a number.
Rule syntax uses comma-separated key-value pairs. Match keys identify the device. Assignment keys take action.
# Match a USB device by vendor and product ID, rename the symlink
SUBSYSTEM=="usb", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="mydevice"
# Match a block device and set permissions
SUBSYSTEM=="block", KERNEL=="sdb", OWNER="jan", GROUP="disk", MODE="0660"
# Run a script when a specific USB is plugged in
SUBSYSTEM=="usb", ATTRS{idVendor}=="1234", ACTION=="add", RUN+="/home/jan/scripts/usb-plugged.sh"
Match operators:
==— match!=— not match
Assignment operators:
=— assign+=— append:=— assign and lock (no further rules can change this)
Finding device attributes for rules
To write a rule for a specific device, you need its attributes. Plug in the device and run:
udevadm info --query=all --name=/dev/sdbOr using the sysfs path:
udevadm info --attribute-walk --path=/sys/bus/usb/devices/1-1Walk up the device tree to find attributes at any level.
Testing and reloading rules
Test what rules would match a device without triggering them:
udevadm test /sys/bus/usb/devices/1-1Reload rules after editing:
sudo udevadm control --reload-rules
sudo udevadm triggerudevadm monitor
Watch uevents in real time — useful when diagnosing device detection issues:
sudo udevadm monitorPlug in a device and watch what events the kernel sends and how udev responds.
/sys and udev together form the kernel's live interface to hardware. /sys lets you read and control hardware state directly. udev automates the response to hardware events. Between them you have everything you need to understand, control, and automate hardware behaviour on Linux.
Next up: kernel parameters and sysctl — tuning the running kernel for performance and security.