mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
character_device_create
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
1. [dep](dep.c)
|
||||
1. [dep2](dep2.c)
|
||||
1. [character_device](character_device.c)
|
||||
1. [character_device_create](character_device_create.c)
|
||||
1. [virt_to_phys](virt_to_phys.c)
|
||||
1. Hardware device drivers
|
||||
1. [pci_min](pci_min.c)
|
||||
|
||||
@@ -19,38 +19,31 @@ and use that for the mknod.
|
||||
- https://unix.stackexchange.com/questions/37829/understanding-character-device-or-character-special-files/371758#371758
|
||||
*/
|
||||
|
||||
#include <asm/uaccess.h> /* copy_from_user, copy_to_user */
|
||||
#include <linux/errno.h> /* EFAULT */
|
||||
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h> /* printk */
|
||||
#include <uapi/linux/stat.h> /* S_IRUSR */
|
||||
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
|
||||
|
||||
#define NAME "lkmc_character_device"
|
||||
|
||||
static int major;
|
||||
|
||||
static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
|
||||
static int show(struct seq_file *m, void *v)
|
||||
{
|
||||
size_t ret;
|
||||
char kbuf[] = {'a', 'b', 'c', 'd'};
|
||||
seq_printf(m, "abcd");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (*off == 0) {
|
||||
if (copy_to_user(buf, kbuf, sizeof(kbuf))) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ret = sizeof(kbuf);
|
||||
*off = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
static int open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations fops = {
|
||||
.llseek = seq_lseek,
|
||||
.open = open,
|
||||
.owner = THIS_MODULE,
|
||||
.read = read,
|
||||
.read = seq_read,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int myinit(void)
|
||||
|
||||
61
kernel_module/character_device_create.c
Normal file
61
kernel_module/character_device_create.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Automatically create the device under /dev on insmod, and remove on rmmod.
|
||||
|
||||
https://stackoverflow.com/questions/5970595/create-a-device-node-in-code/
|
||||
https://stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module-code-of-a-linux-kernel-module/18594761#18594761
|
||||
*/
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
|
||||
|
||||
#define NAME "lkmc_character_device_create"
|
||||
|
||||
static int major = -1;
|
||||
static struct cdev mycdev;
|
||||
static struct class *myclass = NULL;
|
||||
|
||||
static int show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "abcd");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations fops = {
|
||||
.llseek = seq_lseek,
|
||||
.open = open,
|
||||
.owner = THIS_MODULE,
|
||||
.read = seq_read,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int myinit(void)
|
||||
{
|
||||
/* cat /proc/devices */
|
||||
alloc_chrdev_region(&major, 0, 1, NAME "_proc");
|
||||
/* ls /sys/class */
|
||||
myclass = class_create(THIS_MODULE, NAME "_sys");
|
||||
/* ls /dev/ */
|
||||
device_create(myclass, NULL, major, NULL, NAME "_dev");
|
||||
cdev_init(&mycdev, &fops);
|
||||
cdev_add(&mycdev, major, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myexit(void)
|
||||
{
|
||||
device_destroy(myclass, major);
|
||||
class_destroy(myclass);
|
||||
unregister_chrdev_region(major, 1);
|
||||
}
|
||||
|
||||
module_init(myinit)
|
||||
module_exit(myexit)
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -25,7 +25,7 @@ static int show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open(struct inode *inode, struct file *file)
|
||||
static int open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, show, NULL);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
insmod /character_device.ko
|
||||
/mknoddev.sh lkmc_character_device
|
||||
cat /dev/lkmc_character_device
|
||||
# => abcd
|
||||
[ "$(cat /dev/lkmc_character_device)" = 'abcd' ]
|
||||
rm /dev/lkmc_character_device
|
||||
rmmod character_device
|
||||
|
||||
7
rootfs_overlay/character_device_create.sh
Executable file
7
rootfs_overlay/character_device_create.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
insmod /character_device_create.ko
|
||||
dev='/dev/lkmc_character_device_create_dev'
|
||||
[ "$(cat "$dev")" = 'abcd' ]
|
||||
rmmod character_device_create
|
||||
[ ! -e "$dev" ]
|
||||
Reference in New Issue
Block a user