A portfolio-grade Linux kernel driver project for a virtual industrial sensor controller, demonstrating character-device I/O, ioctl ABI design, sysfs/procfs/debugfs interfaces, concurrent buffering, periodic telemetry, Device Tree integration, userspace tooling, automated testing, and QEMU-based validation.
This project implements a virtual industrial sensor controller as a Linux kernel driver.
The driver models a telemetry-producing device that generates sensor samples, maintains device state and statistics, stores samples in a bounded kernel buffer, and exposes controlled interfaces to userspace.
The repository is organized as a complete engineering project rather than a single source file:
- Linux kernel module
- platform-driver architecture
- character-device interface
- ioctl userspace ABI
- sysfs configuration/status
- procfs runtime reporting
- debugfs diagnostics
- bounded concurrent sample buffering
- delayed-work telemetry generation
- Device Tree description and binding
- userspace control utility
- userspace test programs
- QEMU build/run/test tooling
- architecture and concurrency documentation
- GitHub repository templates and CI structure
- Doxygen configuration
- validation/evidence structure
The project is designed to demonstrate the engineering boundary between:
device behavior → Linux kernel subsystems → synchronization → kernel/userspace ABI → userspace control → virtualized validation
It focuses on practical systems-level concepts relevant to Embedded Linux, Linux kernel development, device drivers, firmware and embedded software.
| Engineering Area | Demonstrated Implementation |
|---|---|
| Kernel modules | vsensor.ko |
| Platform driver | platform_driver + probe/remove |
| Character devices | cdev and device registration |
| Userspace ABI | ioctl structures and commands |
| Synchronization | mutexes, spinlocks and wait queues |
| Deferred execution | Linux delayed work |
| Data buffering | bounded circular sample buffer |
| Device configuration | sysfs + ioctl |
| Diagnostics | procfs + debugfs |
| Device Tree | DTS + YAML binding |
| Virtual validation | QEMU |
| Userspace tooling | driverctl |
| Testing | five userspace test programs |
| Repository engineering | CI, issue templates, PR template |
| Documentation | Markdown + Doxygen configuration |
flowchart TB
U["Userspace Applications"]
CLI["driverctl<br/>Control Utility"]
TEST["Userspace Tests"]
ABI["Character Device<br/>read/write/poll/ioctl"]
SYS["sysfs"]
PROC["procfs"]
DBG["debugfs"]
CORE["Virtual Sensor Core Driver"]
BUF["Concurrent Sample Buffer"]
TEL["Telemetry Engine<br/>delayed_work"]
PLAT["Platform Driver"]
DT["Device Tree / Platform Device"]
QEMU["QEMU Environment"]
K["Linux Kernel 6.12"]
U --> CLI
TEST --> ABI
CLI --> ABI
CLI --> SYS
ABI --> CORE
SYS --> CORE
PROC --> CORE
DBG --> CORE
CORE --> BUF
CORE --> TEL
PLAT --> CORE
DT --> PLAT
CORE --> K
QEMU --> K
sequenceDiagram
participant W as Delayed Work
participant D as Sensor Driver
participant B as Sample Buffer
participant U as Userspace
W->>D: Generate sensor sample
D->>D: Update state, sequence and statistics
D->>B: Push sample
B-->>D: Queue result
D->>U: Wake waiting readers
U->>D: read()/poll()/ioctl()
D->>B: Pop sample
B-->>D: Sample
D-->>U: Copy sample to userspace
The driver provides standard Linux character-device operations:
open
release
read
write
poll
unlocked_ioctl
This gives userspace a conventional kernel-device interface.
The userspace ABI is defined in:
driver/include/virtual_sensor_uapi.h
The project defines structured control/status operations such as:
GET_SAMPLE
GET_STATS
GET_CONFIG
SET_CONFIG
START
STOP
RESET
This separates structured device control from simple textual interfaces.
The telemetry subsystem uses Linux delayed work to periodically generate virtual sensor samples.
The driver maintains state including:
- sequence number
- timestamp
- temperature
- vibration
- status flags
- generated sample count
- read count
- dropped sample count
- fault event count
- open count
Sensor samples are stored in a bounded circular buffer.
The implementation uses:
spin_lock_irqsave()
spin_unlock_irqrestore()
mutex
wait queue
The buffer protects producer/consumer state while the device-state lock protects broader configuration and runtime state.
This separation is important for demonstrating kernel concurrency design rather than relying on one global lock.
The driver exposes runtime configuration/status through sysfs attributes including:
enabled
period_ms
sequence
These interfaces provide a Linux-native way to inspect and control device state.
A procfs status interface provides human-readable runtime information and telemetry statistics.
The project provides a debugfs interface for development-time diagnostics and driver observability.
The repository contains:
dts/virtual-sensor.dts
dts/bindings/prasanth,virtual-sensor.yaml
The binding describes the virtual industrial sensor device and its configurable properties.
The project includes a QEMU environment for reproducible virtual validation.
Where a normal x86 QEMU configuration does not expose the intended Device Tree path, the driver architecture includes a controlled virtual platform-device path so that driver lifecycle and userspace interaction can still be exercised.
.
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── workflows/
│ │ └── ci.yml
│ └── pull_request_template.md
│
├── docs/
│ ├── ARCHITECTURE.md
│ ├── BUILD.md
│ ├── CONCURRENCY.md
│ ├── DEBUGGING.md
│ ├── DEVICE_TREE.md
│ ├── DRIVER_MODEL.md
│ ├── PHASE_1.md
│ ├── TESTING.md
│ ├── USERSPACE_ABI.md
│ └── RELEASE_CHECKLIST.md
│
├── driver/
│ ├── core/
│ │ ├── vsensor_buffer.c
│ │ ├── vsensor_buffer.h
│ │ ├── vsensor_core.c
│ │ ├── vsensor_debugfs.c
│ │ ├── vsensor_ioctl.c
│ │ ├── vsensor_sysfs.c
│ │ └── vsensor_telemetry.c
│ ├── include/
│ │ ├── virtual_sensor.h
│ │ └── virtual_sensor_uapi.h
│ ├── irq/
│ ├── platform/
│ ├── kconfig
│ └── Makefile
│
├── dts/
├── qemu/
├── scripts/
├── tests/
├── tools/
├── userspace/
├── screenshots/
├── Doxyfile
├── Makefile
└── README.md
The current validation environment reports:
Linux kernel: 6.12.0
Driver build: Kbuild
Userspace: C
Virtual test: QEMU
The driver artifact has been produced as:
vsensor.ko
with verified metadata:
version: 1.0.0
name: vsensor
vermagic: 6.12.0 SMP preempt mod_unload
The project builds the external kernel module against a prepared Linux kernel source tree.
Example:
KDIR="$HOME/embedded-kernel-project/linux"
BUILD="$HOME/driver-build"
make -C "$KDIR" M="$BUILD" clean
make -C "$KDIR" M="$BUILD" modulesInspect the resulting module:
modinfo "$BUILD/vsensor.ko"make -C userspace/driverctl clean
make -C userspace/driverctlOutput:
userspace/driverctl/driverctl
The current project validation produced the userspace executable successfully.
The repository contains five test programs:
userspace/tests/test_basic.c
userspace/tests/test_concurrency.c
userspace/tests/test_errors.c
userspace/tests/test_ioctl.c
userspace/tests/test_poll.c
They are built into:
build/tests/
The validated build produced:
test_basic
test_concurrency
test_errors
test_ioctl
test_poll
Build example:
mkdir -p build/tests
cc -std=c11 -Wall -Wextra -Wpedantic -O2 \
-I./driver/include \
userspace/tests/test_basic.c \
-o build/tests/test_basic
cc -std=c11 -Wall -Wextra -Wpedantic -O2 -pthread \
-I./driver/include \
userspace/tests/test_concurrency.c \
-o build/tests/test_concurrency
cc -std=c11 -Wall -Wextra -Wpedantic -O2 \
-I./driver/include \
userspace/tests/test_errors.c \
-o build/tests/test_errors
cc -std=c11 -Wall -Wextra -Wpedantic -O2 \
-I./driver/include \
userspace/tests/test_ioctl.c \
-o build/tests/test_ioctl
cc -std=c11 -Wall -Wextra -Wpedantic -O2 \
-I./driver/include \
userspace/tests/test_poll.c \
-o build/tests/test_pollThe repository provides:
qemu/build-kernel.sh
qemu/build-rootfs.sh
qemu/run-qemu.sh
qemu/run-tests.sh
The intended validation sequence is:
bash qemu/build-kernel.sh
bash qemu/build-rootfs.sh
bash qemu/run-qemu.sh
bash qemu/run-tests.shThe project has already produced the required QEMU artifacts during development, including:
build/kernel/bzImage
build/rootfs.cpio.gz
build/dtb/virtual-sensor.dtb
The final release should retain the strongest terminal/QEMU evidence in:
screenshots/
test_basic
test_concurrency
test_errors
test_ioctl
test_poll
tests/integration/
tests/scripts/run_userspace_tests.sh
The project validation process covers:
- kernel-module compilation
- module metadata inspection
- userspace utility compilation
- userspace test compilation
- QEMU image preparation
- QEMU execution
- driver/userspace integration
- source-tree audit
- repository hygiene
Different categories of shared state use different synchronization mechanisms.
The driver uses a mutex for broader device-state/configuration protection:
struct mutex state_lock;The bounded buffer uses spinlock-based protection:
spin_lock_irqsave()
spin_unlock_irqrestore()A wait queue allows readers to sleep until data becomes available instead of busy-waiting.
Telemetry generation uses:
struct delayed_workrather than creating an unnecessary dedicated kernel thread.
| Interface | Primary Purpose |
|---|---|
| Character device | Primary device interaction |
read() |
Retrieve queued samples |
write() |
Textual control path |
poll() |
Event-driven waiting |
ioctl() |
Structured configuration/control |
sysfs |
Device configuration/status |
procfs |
Human-readable runtime status |
debugfs |
Development diagnostics |
The project therefore demonstrates multiple Linux interfaces instead of forcing every operation through a single ABI.
The implementation includes explicit handling for conditions such as:
- invalid userspace arguments
- invalid configuration values
- failed userspace copies
- empty buffers
- full buffers
- registration failures
- device/class creation failures
- sysfs initialization failures
- debugfs initialization failures
- platform-device registration failures
Representative kernel error codes include:
-EINVAL
-EFAULT
-ENODEV
-EAGAIN
-ENOSPC
-ENOMEM
-ENOTTY
The repository contains:
scripts/build_driver.sh
scripts/build_userspace.sh
scripts/static_analysis.sh
tools/check_kernel_style.sh
tools/collect_evidence.sh
The repository audit performed during development covered:
Source-tree inventory
Empty-file detection
Placeholder/TODO scan
Suspicious stub detection
Debug-print scan
Secret/credential scan
Git whitespace validation
Generated-artifact filtering
Development backup material was removed before release preparation.
Generated build outputs are excluded through .gitignore.
The documentation is organized by engineering topic:
docs/ARCHITECTURE.md
docs/BUILD.md
docs/CONCURRENCY.md
docs/DEBUGGING.md
docs/DEVICE_TREE.md
docs/DRIVER_MODEL.md
docs/PHASE_1.md
docs/TESTING.md
docs/USERSPACE_ABI.md
Doxygen is configured through:
Doxyfile
Generate API documentation with:
doxygen DoxyfileGenerated documentation should remain a build artifact unless the repository explicitly chooses to publish it.
Validation evidence belongs in:
screenshots/
Recommended final evidence set:
| Evidence | Suggested File |
|---|---|
| Driver build | 01-driver-build.png |
| Module metadata | 02-modinfo.png |
| Userspace build | 03-userspace-build.png |
| Test build/results | 04-tests.png |
| QEMU boot | 05-qemu-boot.png |
| Driver probe | 06-driver-probe.png |
| Device node | 07-device-node.png |
| ioctl | 08-ioctl.png |
| sysfs | 09-sysfs.png |
| procfs/debugfs | 10-observability.png |
| Final validation | 11-final-validation.png |
A short terminal transcript can accompany screenshots where it gives stronger reproducibility than an image alone.
When the final screenshots are captured, they can be referenced here with normal GitHub-relative image links.
The repository is prepared for a professional GitHub workflow:
.github/
├── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ └── feature_request.md
├── workflows/
│ └── ci.yml
└── pull_request_template.md
Repository governance files include:
CONTRIBUTING.md
CODE_OF_CONDUCT.md
SECURITY.md
CHANGELOG.md
LICENSE
The CI workflow is intended to verify userspace builds and repository validation automatically.
This project demonstrates hands-on work with:
- Linux kernel modules
- platform drivers
- character devices
- Kbuild
- Device Tree
- ioctl ABI design
- sysfs
- procfs
- debugfs
- wait queues
- mutexes
- spinlocks
- delayed work
- bounded circular buffers
- kernel/userspace data exchange
- QEMU
- embedded Linux validation
- defensive error handling
- userspace testing
- repository CI
- engineering documentation
This is a virtual sensor controller, not a physical industrial sensor driver.
Therefore:
- sensor values are simulated
- no physical SPI/I2C sensor is required
- QEMU provides the virtual validation environment
- hardware-specific acquisition would require a real sensor backend
- physical interrupt/DMA behavior would be added when integrating actual hardware
These limitations are deliberate. The project concentrates on Linux driver architecture, synchronization, ABI design, observability and reproducible validation.
Potential next-stage engineering extensions include:
- real I2C/SPI sensor backend
- hardware IRQ-driven acquisition
- DMA-based data path
- kernel tracepoints
- ftrace/perf instrumentation
- fault-injection testing
- KUnit tests
- broader kernel-version CI
- automated QEMU boot tests
- performance and latency benchmarks
- industrial protocol integration
- Linux kernel driver implementation
- Driver module build
-
vsensor.kometadata verification - Userspace utility build
- Five userspace test builds
- QEMU kernel/rootfs/DTB artifacts generated
- Source-tree audit
- Development backup removed
- Generated build artifacts excluded from Git
- Placeholder scan
- Secret/credential scan
- Repository whitespace validation
- Professional GitHub structure
- Doxygen configuration
- Professional README
- Final QEMU execution capture
- Capture final terminal evidence
- Populate
screenshots/ - Review README rendering after assets are added
- Final Git staging audit
- Create first release commit
- Push repository to GitHub
- Verify GitHub-rendered README
- Verify CI result
This distinction is intentional: development validation is complete enough to package the project, while the final public-release evidence still needs to be captured.
Embedded Systems • Linux Device Drivers • Embedded Software • Systems Programming
B.Tech — Electronics and Communication Engineering (ECE) Lendi Institute of Engineering and Technology Vizianagaram, Andhra Pradesh, India Expected graduation: 2027
Embedded Linux
Linux Kernel
Device Drivers
Firmware Development
RTOS
Systems Programming
Embedded C
- GitHub:
github.com/prasanth-vedula - Email:
prasanthvedula2006@gmail.com
See the repository's:
LICENSE
The repository should use the license declared by the actual LICENSE file; this README intentionally does not invent a license designation if the file has not yet been populated.
This project is intended to demonstrate the complete engineering lifecycle:
Design
↓
Implement
↓
Build
↓
Test
↓
Validate
↓
Document
↓
Collect Evidence
↓
Package
↓
Review
↓
Release
The objective is not simply to demonstrate that a kernel module can compile.
The objective is to demonstrate that an embedded-systems engineer can take a systems problem, design a kernel/userspace boundary, implement synchronization and device behavior, build and validate it in a virtual environment, document the architecture, and package the result as a professional engineering repository.
This repository includes reproducible engineering evidence from the build, driver, userspace, QEMU, ABI, and final release-validation stages.
PNG files are presentation snapshots generated directly from the projects actual validation records. The corresponding TXT/MD files remain the raw evidence records.





