Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Linux Kernel Modules and Device Drivers

A progression of small, self-contained Linux kernel modules that build up from a bare "hello world" in kernel space to a working character device driver with dynamic major/minor allocation.

Language Platform

Overview

Each module isolates a single kernel or driver concept so it is clear what changed from one to the next. Together they demonstrate:

  • The loadable kernel module lifecycle: module_init / module_exit, insmod / rmmod, and kernel logging through printk (viewed with dmesg).
  • Passing parameters into a module at load time with module_param.
  • Registering device numbers, both with a statically chosen major (register_chrdev) and with dynamic allocation (alloc_chrdev_region).
  • The file_operations interface wiring open / read / write / release on a /dev node through to driver callbacks.
  • Moving data across the user/kernel boundary with copy_to_user and copy_from_user.
  • Managing kernel memory with kmalloc, krealloc, and kfree, including a device buffer that grows on demand.

A separate board-pynq-z1/ wing documents taking the character driver off the host x86_64 kernel and onto ARM hardware by building a Yocto image and cross-compiling for the target (see below).

Prerequisites

  • Linux kernel headers matching the running kernel: linux-headers-$(uname -r).
  • A C toolchain and build tools: gcc, make (for example, Debian/Ubuntu build-essential).
  • Root privileges to load and unload modules and to create device nodes.

Every module builds against the running kernel via the standard kbuild pattern: make -C /lib/modules/$(uname -r)/build M=$(PWD) modules.

The board-pynq-z1/ wing is different: it targets a Pynq-Z1 board (Xilinx Zynq-7000, dual Cortex-A9, armv7 hard-float) running a Yocto Scarthgap (5.0 LTS) image built from source. That path needs the Yocto build dependencies and a cross-toolchain, all documented inside that directory. It is a documentation and configuration wing (build notes plus conf/ snapshots); the heavy Yocto tree lives outside the repo.

Modules

  • hello_kernel/ (mymodule.c): a minimal loadable module with __init / __exit entry points that log a message via printk. The smallest complete module.
  • hello_mod/ (hello_world.c): a second minimal module using KERN_INFO log levels and the MODULE_LICENSE / MODULE_AUTHOR / MODULE_DESCRIPTION metadata macros.
  • mod_parameter/ (module_parameters.c): declares module parameters (howMany as int, whom as charp) with module_param, then prints the greeting howMany times at load. Shows how values are supplied at insmod time.
  • dev_num/ (dev_num.c): registers a character device number with a statically defined major (91) via register_chrdev, and provides open / release callbacks through a file_operations table. test.c is a user-space program that opens the device node and reports success or failure.
  • chardev/ (chardev.c): a full character device driver. It allocates a major/minor pair dynamically with alloc_chrdev_region, registers a cdev, and implements open, release, read, and write. Reads and writes cross the user/kernel boundary with copy_to_user / copy_from_user, and the backing buffer starts at 1024 bytes and grows on demand with krealloc. test_app.c is an interactive menu-driven program that opens /dev/mychardev and writes to and reads from it.
  • board-pynq-z1/: documentation and configuration for the cross-compile wing. Contains README.md (plan and phase tracking), TUTORIAL.md (a reproducible, start-to-finish Yocto Scarthgap build log for the Pynq-Z1), and conf/ (bblayers.conf and a local.conf snippet). The build tree itself is kept outside the repo.

Building and loading

Build any module by running make in its directory:

cd chardev            # or hello_kernel, hello_mod, mod_parameter, dev_num
make                  # builds the .ko against the running kernel

Load it, inspect the kernel log, then unload it:

sudo insmod chardev.ko
dmesg | tail          # view init messages and the allocated major/minor
sudo rmmod chardev

Pass parameters at load time (mod_parameter):

sudo insmod module_parameters.ko howMany=3 whom=World
dmesg | tail
sudo rmmod module_parameters

Testing the character device (chardev): the module allocates its major number dynamically and does not create the /dev node automatically, so read the major from the log and create the node by hand:

sudo insmod chardev.ko
dmesg | tail                              # note the "major X and minor 0" line
sudo mknod /dev/mychardev c <major> 0     # use the major from dmesg
sudo chmod 666 /dev/mychardev

echo "hello" > /dev/mychardev             # write
cat /dev/mychardev                        # read back

# or use the interactive helper (built by the chardev Makefile)
./test_app

sudo rm /dev/mychardev
sudo rmmod chardev

The dev_num module works the same way (static major 91): create the node with sudo mknod /dev/<name> c 91 0, then open it (its test.c opens /dev/mydevices).

A note on safety: build against a kernel-headers version that matches the running kernel, and load modules on a VM or test machine rather than anything you care about.

Project layout

  • hello_kernel/ — minimal module with init / exit and printk.
  • hello_mod/ — minimal module with metadata macros and log levels.
  • mod_parameter/ — module parameters supplied at load time.
  • dev_num/ — static device-number registration with open / release callbacks.
  • chardev/ — character device driver: dynamic major/minor, read / write, growable buffer, plus a user-space test app.
  • board-pynq-z1/ — Yocto + ARM cross-compile wing (docs and build config).

About

Linux kernel modules and a character device driver with dynamic major/minor allocation

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages