proc, sysfs and Mounting Filesystems
Understand Linux pseudo filesystems, the mount command, and installing kernel modules — free embedded Linux course
Two of the most useful windows into a running Linux kernel aren’t files on disk at all — they’re generated live, on demand, by the kernel itself. In this lecture, part of EmbeddedPathashala’s free linux kernel development course, we cover the proc and sysfs pseudo filesystems, how the mount command attaches any filesystem into your directory tree, and how kernel modules get installed into a root filesystem. If you’re staging a minimal embedded Linux system, these three pieces are what turn a static tree of files into a live, inspectable, extensible operating system.
sysfs
pseudo filesystem
mount command
kernel modules
modprobe
free linux development course
What You Will Learn
- What a pseudo filesystem actually is
- proc: purpose, history, and layout
- sysfs: an ordered view of the device model
- The mount command and its syntax
- Mounting pseudo filesystems that have no device node
- Installing kernel modules into a root filesystem
- Common mistakes and troubleshooting tips
Prerequisites
This lecture builds on the previous one on Linux device nodes. You should already be comfortable with basic shell usage and know what a root filesystem staging directory looks like. Some familiarity with the idea of the kernel exposing information to user space will help, but we build that up from scratch here.
What Is a Pseudo Filesystem?
A regular filesystem — ext4, FAT32, XFS — stores data physically on a block device and reads it back from disk when you open a file. A pseudo filesystem looks identical from the outside (you still cd into it and cat files inside it), but nothing is stored on disk at all. Every time you read a file inside a pseudo filesystem, a function inside the kernel runs on the spot and formats the answer fresh. Write to a writable pseudo file, and a kernel function is invoked with your new data, validating it and updating live kernel state if it’s acceptable. This gives user space two pseudo filesystems worth knowing well: proc and sysfs.
cat /home/user/notes.txt –> ext4 driver –> disk blocks –> data returnedPseudo file (proc/sysfs):
cat /proc/cpuinfo –> VFS –> kernel show() callback –> formatted on the fly –> data returned
(nothing was ever stored on a disk)
The proc Filesystem
proc has existed since the early days of Linux, and its original purpose was to expose process information to user space — hence the name. For every running process, the kernel maintains a directory /proc/<PID> containing files that describe that process’s memory maps, open file descriptors, command line, and state. Familiar tools like ps and top aren’t magic — they simply read these files and format the output nicely.
Beyond per-process data, proc also exposes system-wide information and tunables:
| Path | What it exposes |
|---|---|
| /proc/cpuinfo | Details about the installed CPU(s) |
| /proc/interrupts | Live interrupt counts per IRQ line |
| /proc/meminfo | Current memory usage breakdown |
| /proc/sys/* | Tunable kernel parameters for scheduling, memory management, and networking (also reachable via the sysctl command) |
The authoritative reference for what you’ll find under proc is the proc(5) man page, which is worth bookmarking — the layout has grown fairly organically over three decades and isn’t always self-explanatory.
Why sysfs Was Introduced
Over time, the number of files under proc and the logic behind their layout became fairly chaotic — files were added wherever seemed convenient at the time, without an overarching structure. Starting with Linux 2.6, the kernel introduced sysfs to export a subset of that same kind of data, but in a strictly ordered hierarchy tied directly to the kernel’s internal device model — every device, driver, and bus shows up in a predictable location, connected to related objects through symlinks. Where proc is historically about processes and system tuning, sysfs is specifically about devices and how they relate to each other — buses, drivers, classes, and the physical/logical device tree.
Mounting proc and sysfs
Both pseudo filesystems need to be mounted onto real directories before you can use them — typically /proc and /sys respectively:
$ sudo mkdir -p /proc /sys
$ sudo mount -t proc proc /proc
$ sudo mount -t sysfs sysfs /sys
Understanding the mount Command
The mount command attaches one filesystem onto a directory within another, building up the overall directory hierarchy you see when you run ls /. The filesystem mounted right at boot time by the kernel itself is called the root filesystem — everything else gets layered on top of it. The general syntax is:
mount [-t vfstype] [-o options] device directory
You specify the filesystem type (vfstype), the block device node the data lives on, and the directory you want to attach it to. For example, mounting an SD card’s first partition, formatted as ext4, onto /mnt:
$ sudo mount -t ext4 /dev/mmcblk0p1 /mnt
In some cases you can omit -t entirely and let the kernel probe the device to detect the filesystem type automatically.
The Curious Case of “device” for Pseudo Filesystems
Look again at the proc mount command above: mount -t proc proc /proc. There is no block device backing a pseudo filesystem — no /dev/proc exists, because proc isn’t a real filesystem stored anywhere. But the mount command’s syntax requires something in the “device” position regardless. The convention is to just repeat the filesystem type as a placeholder string; the kernel ignores its actual value for pseudo filesystems. These two commands do exactly the same thing:
$ sudo mount -t proc proc /proc
$ sudo mount -t proc nodevice /proc
Using the filesystem type as the device placeholder is simply the common convention — it makes the command self-documenting even though the string itself is never actually inspected as a real device path.
Installing Kernel Modules Into a Root Filesystem
If your kernel build produces loadable modules, they need to land inside your root filesystem before the target can load them at runtime. The standard way to do this is the kernel’s own modules_install build target, pointed at your staging directory:
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
INSTALL_MOD_PATH=~/ep_rootfs modules_install
This copies every built module into /lib/modules/<kernel-version>/ inside your staging tree, along with the metadata files (modules.dep, modules.alias, and friends) that modprobe relies on to resolve dependencies and aliases automatically.
|
| modules_install
v
rootfs/lib/modules/<version>/*.ko + modules.dep, modules.aliasIf you rebuild the kernel with a new version string,
the old module directory becomes unreachable by modprobe
until the rootfs is updated too.
This step quietly creates a dependency between your kernel build and your root filesystem build: if you bump the kernel version, the module directory name changes, and old modules will no longer be found unless you update the root filesystem to match. This is one of the most common causes of “my driver won’t load” reports on embedded boards after a kernel upgrade.
Real-World Use Cases
- Debugging a hung system: reading
/proc/<PID>/statusand/proc/interruptsto see what a stuck process or IRQ storm is doing, without any special tooling. - Runtime tuning: adjusting scheduler or memory management behavior through
/proc/syswithout a reboot. - Driver bring-up: checking
/sys/class/and/sys/bus/to confirm your new driver registered correctly and is bound to the expected device. - Custom root filesystems: ensuring proc, sysfs, and any needed kernel modules are wired up correctly so the board behaves like a normal Linux system once it boots.
Common Mistakes and Troubleshooting
Forgetting to mount proc or sysfs at all
If your init script doesn’t mount these, tools like ps will simply fail or return nothing, and driver debugging under /sys becomes impossible. Always mount both early in your init sequence, before starting other services.
Mounting proc onto the wrong directory
Mounting it somewhere other than /proc will silently break every tool that hardcodes that path, which is most of them.
Mismatched kernel version and module directory
If modprobe reports “module not found” after a kernel rebuild, check whether /lib/modules/$(uname -r) actually exists on the target and matches the running kernel version string exactly.
Best Practices
- Mount proc and sysfs as one of the very first steps in your init sequence — many other tools implicitly depend on them.
- Automate module installation as part of your build pipeline (INSTALL_MOD_PATH) rather than copying
.kofiles by hand. - Keep kernel and root filesystem builds versioned together so the module directory always matches the running kernel.
Performance and Security Considerations
Reading from proc and sysfs is cheap compared to disk I/O since nothing touches storage, but frequent polling of many files (as some monitoring tools do) still costs CPU time formatting output on every read — batch your reads where possible. On the security side, some entries under /proc/sys and certain sysfs attributes can alter kernel behavior or expose sensitive information (like kernel addresses used for security hardening); restrict who can write to sensitive proc/sysfs paths, and avoid exposing raw kernel pointers on production systems where kptr_restrict-style protections exist for exactly this reason.
Summary and Key Takeaways
- proc and sysfs are pseudo filesystems: nothing is stored on disk, everything is generated live by the kernel on each read.
- proc originated to expose per-process information and has since accumulated broader system state and tunables.
- sysfs, introduced in Linux 2.6, exports an ordered view of the kernel’s device model.
- The mount command’s syntax is
mount -t vfstype device directory; pseudo filesystems use the filesystem type itself as a placeholder “device.” - Kernel modules must be installed into the root filesystem’s
/lib/modules/<version>directory before modprobe can find them, creating a version dependency between kernel and rootfs.
Conclusion
proc and sysfs turn a Linux system from a static collection of files into something you can inspect and tune live, and understanding both is a core skill in any serious free linux kernel development course. Combined with a correct mount setup and properly installed kernel modules, your root filesystem goes from “a pile of binaries” to a fully functioning, debuggable Linux environment. Next up, we’ll look at how to actually get that staged root filesystem onto your target hardware — as a ramdisk, a disk image, or over the network via NFS.
Frequently Asked Questions
What’s the real difference between proc and sysfs?
proc is historically about process information and general kernel tunables, with a layout that grew organically. sysfs is a strictly ordered export of the kernel’s internal device model, introduced later specifically to be tidier and more predictable.
Why does mounting proc need a “device” argument if there’s no real device?
The mount syscall’s interface expects something in that position regardless of filesystem type. For pseudo filesystems, the kernel ignores the actual string, so convention is to reuse the filesystem type name as a self-documenting placeholder.
Can I write to files under /proc/sys?
Many are writable and let you tune kernel behavior live, provided you have sufficient permissions and the data you write is in the format the kernel expects; invalid input is rejected.
Where do kernel modules get installed on the target?
Under /lib/modules/<kernel-version>/ inside the root filesystem, along with dependency and alias metadata files that modprobe reads.
Why did my modules stop loading after a kernel update?
Almost always a version mismatch — the module directory name is tied to the exact kernel version string, so an updated kernel needs an updated module directory to match.
Is sysfs replacing proc entirely?
No — they coexist and serve overlapping but distinct purposes; proc remains the standard place for process and general kernel information even though sysfs handles device topology more cleanly.
Keep Learning Embedded Linux for Free
This lecture is part of EmbeddedPathashala’s free linux kernel development course, taking you from device nodes to a fully bootable root filesystem.
