Challenge

Project 1 - Develop the full featured char driver as a loaded module

KConfig:





menuconfig CHARACTER_DEVICE_DRIVER

tristate "Advanced Character Device Driver"

help

This is an advanced character device driver with features like

blocking I/O, dynamic memory, and single-user access.

if CHARACTER_DEVICE_DRIVER

config CHAR_MAX_MEM_SIZE

int "Maximum memory size (in bytes)"

default 1024

help

Configure the maximum memory size for the character device.

endif

Kernel Module Code:

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/proc_fs.h>

#include <linux/uaccess.h>

#include <linux/slab.h>

#include <linux/wait.h>

#include <linux/mutex.h>

#define DEVICE_NAME "char_driver"

#define PROC_FILENAME "char_driver_size"

static int major;

static char *device_buffer;

static size_t buffer_size;

static size_t read_offset = 0, write_offset = 0;

static size_t max_memory = 1024; // Default max memory size

module_param(max_memory, ulong, 0444);

static wait_queue_head_t read_queue, write_queue;

static struct mutex device_lock;

static struct proc_dir_entry *proc_file;

static ssize_t char_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {

...

}

static ssize_t char_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) {

...

}

static loff_t char_llseek(struct file *filp, loff_t offset, int whence) {

...

}

static int char_open(struct inode *inode, struct file *filp) {

...

}

static int char_release(struct inode *inode, struct file *filp) {

...

}

static const struct file_operations fops = {

.owner = THIS_MODULE,

.read = char_read,

.write = char_write,

.llseek = char_llseek,

.open = char_open,

.release = char_release,

};

static ssize_t proc_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) {

char buf[128];

int len = snprintf(buf, sizeof(buf), "Buffer size: %zu bytes\n", buffer_size);

return simple_read_from_buffer(user_buf, count, ppos, buf, len);

}

static const struct proc_ops proc_ops = {

.proc_read = proc_read,

};

static int __init char_init(void) {

major = register_chrdev(0, DEVICE_NAME, &fops);

if (major < 0) return major;

device_buffer = kzalloc(max_memory, GFP_KERNEL);

if (!device_buffer) return -ENOMEM;

proc_file = proc_create(PROC_FILENAME, 0444, NULL, &proc_ops);

if (!proc_file) {

unregister_chrdev(major, DEVICE_NAME);

kfree(device_buffer);

return -ENOMEM;

}

init_waitqueue_head(&read_queue);

init_waitqueue_head(&write_queue);

mutex_init(&device_lock);

pr_info("Char driver loaded with major %d\n", major);

return 0;

}

static void __exit char_exit(void) {

proc_remove(proc_file);

unregister_chrdev(major, DEVICE_NAME);

kfree(device_buffer);

pr_info("Char driver unloaded\n");

}

module_init(char_init);

module_exit(char_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Your Name");

MODULE_DESCRIPTION("Advanced Character Device Driver");

MODULE_VERSION("1.0");

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.