mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-13 20:12:26 +00:00
66 lines
1.3 KiB
C
66 lines
1.3 KiB
C
/*
|
|
Allows us to create device files with given file operations with mknoc c X.
|
|
|
|
Usage:
|
|
|
|
/character_device.sh
|
|
|
|
The major number determines which module owns the device file.
|
|
|
|
minor is to differentiate between multiple instances of the device,
|
|
e.g. two NVIDIA GPUs using the same kernel module.
|
|
|
|
Major numbers are allocated automatically by the kernel,
|
|
so we need to check /proc/devices to find out the assigned number.
|
|
*/
|
|
|
|
#include <asm/uaccess.h> /* copy_from_user, copy_to_user */
|
|
#include <linux/errno.h> /* EFAULT */
|
|
#include <linux/fs.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/kernel.h> /* min */
|
|
#include <linux/module.h>
|
|
#include <linux/printk.h> /* printk */
|
|
#include <uapi/linux/stat.h> /* S_IRUSR */
|
|
|
|
#define NAME "lkmc_character_device"
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
static int major;
|
|
|
|
static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
|
|
{
|
|
size_t ret;
|
|
char kbuf[] = {'a', 'b', 'c', 'd'};
|
|
|
|
ret = 0;
|
|
if (*off == 0) {
|
|
if (copy_to_user(buf, kbuf, sizeof(kbuf))) {
|
|
ret = -EFAULT;
|
|
} else {
|
|
ret = sizeof(kbuf);
|
|
*off = 1;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static const struct file_operations fops = {
|
|
.read = read,
|
|
};
|
|
|
|
static int myinit(void)
|
|
{
|
|
major = register_chrdev(0, NAME, &fops);
|
|
return 0;
|
|
}
|
|
|
|
static void myexit(void)
|
|
{
|
|
unregister_chrdev(major, NAME);
|
|
}
|
|
|
|
module_init(myinit)
|
|
module_exit(myexit)
|