Skip to content

Instantly share code, notes, and snippets.

@robbmanes
Created November 23, 2021 17:16
Show Gist options
  • Save robbmanes/0f691939333a2cba48c3e634bd1ca1f4 to your computer and use it in GitHub Desktop.
Save robbmanes/0f691939333a2cba48c3e634bd1ca1f4 to your computer and use it in GitHub Desktop.
Example character device driver for generating large minor numbers
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#define BIGDUMMY_MINOR 65536
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robb Manes");
MODULE_DESCRIPTION("Simulates a dummy device with a pre-defined minor number.");
MODULE_VERSION("0.1");
static int bigdummy_open(struct inode *inode, struct file *file);
static int bigdummy_release(struct inode *inode, struct file *file);
static long bigdummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static ssize_t bigdummy_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
static ssize_t bigdummy_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
struct bigdummy_cdev {
struct cdev cdev;
};
struct file_operations bigdummy_fops = {
.owner = THIS_MODULE,
.open = bigdummy_open,
.release = bigdummy_release,
.unlocked_ioctl = bigdummy_ioctl,
.read = bigdummy_read,
.write = bigdummy_write
};
static int majordev;
static struct class *bigdummy_class = NULL;
static struct bigdummy_cdev bigdummy_data[1];
static int bigdummy_open(struct inode *inode, struct file *file)
{
printk("bigdummy: open not implemented\n");
return 0;
}
static int bigdummy_release(struct inode *inode, struct file *file)
{
printk("bigdummy: release not implemented\n");
return 0;
}
static long bigdummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk("bigdummy: ioctl not implemented\n");
return 0;
}
static ssize_t bigdummy_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
printk("bigdummy: read not implemented\n");
return 0;
}
static ssize_t bigdummy_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
printk("bigdummy: write not implemented\n");
return 0;
}
static int __init bigdummy_load(void)
{
int err;
dev_t dev;
printk("Preparing dummy device...\n");
err = alloc_chrdev_region(&dev, 0, 1, "bigdummy");
if (err) {
printk("Failed to load, exiting bigdummy module init...\n");
return -1;
}
majordev = MAJOR(dev);
bigdummy_class = class_create(THIS_MODULE, "bigdummy");
cdev_init(&bigdummy_data[0].cdev, &bigdummy_fops);
bigdummy_data[0].cdev.owner = THIS_MODULE;
cdev_add(&bigdummy_data[0].cdev, MKDEV(majordev, BIGDUMMY_MINOR), 1);
device_create(bigdummy_class, NULL, MKDEV(majordev, BIGDUMMY_MINOR), NULL, "bigdummy-%d", 0);
printk("Dummy device finished initialization.\n");
return 0;
}
static void __exit bigdummy_unload(void)
{
return;
}
module_init(bigdummy_load);
module_exit(bigdummy_unload);
obj-m += bigdummy.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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment