Project 1 - Develop the full featured char driver as a loaded module
Overview of the Project:
- Kconfig build system
- The module should be added to the Kernel configuration Kconfig build system with tristate option.
- Char driver should be of
- Open --> Only one user is allowed to open the device. Other users should be blocked.
- Read and write operation --> store the data to the dynamically allocated memory and read from it.
- Seek --> able to move the offset of read/write location.
- Max memory size --> configurable through compile time, load time.
- Blocked Read /write --> whenever data is not available to read, driver should wait till it is available. Similarly during write, when enough memory is available.
- /proc/char_driver_size --> Create the proc file char_driver_size which should reflect the size of memory allocated to the char driver.
Goals
- The students will be capable of writing and building the loadable linux kernel module.
- The module will have all the advanced capabilities of the character device module.
Key Highlights of the Project:
- Linux kernel module compilation, installation and removal.
- Creation of the Character device drivers using mknod and major & minor number.
- Interacting with the character device using the user space application like cat and echo.
- It helps to understand the concepts like modules, makefile, major & minor number, different memory allocation techniques.
Deliverables of this project:
- The Linux kernel module which is in .ko format.
- Makefile used for compiling for the kernel module.
- With the help of virtual file system procfs, the user is intimated with the size of memory allocated to the char device.
- User application to interact with the character devices and print to the console.
Expected Outcomes:
- Able to compile and install the Linux kernel module .
- Able to use different kernel module utilities like insmod, modprobe and rmmod.
- Able to create the char driver and link it with the device driver.
- Able to use the different read mechanisms like blocked read and non blocked read.
- Able to learn the virtual file system like procfs.
Code:
char_driver.c :
#include
#include
#include
#include
MODULE_LICENSE("GPL");
static int device_opened = 0; // Track device open status
static int char_device_open(struct inode *inode, struct file *file)
{
if (device_opened)
return -EBUSY; // Device is already open
device_opened = 1;
return 0;
}
static int char_device_release(struct inode *inode, struct file *file)
{
device_opened = 0;
return 0;
}
static struct file_operations fops = {
.open = char_device_open,
.release = char_device_release,
};
static int __init char_device_init(void)
{
// Register the character device
int ret = register_chrdev(0, "char_driver", &fops);
if (ret < 0) {
printk(KERN_INFO "char_driver: Failed to register a device\n");
return ret;
}
printk(KERN_INFO "char_driver: Device registered successfully\n");
return 0;
}
static void __exit char_device_exit(void)
{
// Unregister the character device
unregister_chrdev(0, "char_driver");
printk(KERN_INFO "char_driver: Device unregistered\n");
}
module_init(char_device_init);
module_exit(char_device_exit);
char_test.c :
#include
#include
#include
#define DEVICE "/dev/char_driver"
int main() {
int fd;
char buf[1024];
fd = open(DEVICE, O_RDWR);
if (fd < 0) {
perror("Failed to open the device...");
return -1;
}
printf("Reading from the device...\n");
read(fd, buf, 1024);
printf("Data read: %s\n", buf);
printf("Writing to the device...\n");
write(fd, "Hello from user space!", 22);
close(fd);
return 0;
}
Makefile:
obj-m += char_driver.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Screenshots:


