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. [dep](dep.c)
|
||||||
1. [dep2](dep2.c)
|
1. [dep2](dep2.c)
|
||||||
1. [character_device](character_device.c)
|
1. [character_device](character_device.c)
|
||||||
|
1. [character_device_create](character_device_create.c)
|
||||||
1. [virt_to_phys](virt_to_phys.c)
|
1. [virt_to_phys](virt_to_phys.c)
|
||||||
1. Hardware device drivers
|
1. Hardware device drivers
|
||||||
1. [pci_min](pci_min.c)
|
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
|
- 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/fs.h> /* register_chrdev, unregister_chrdev */
|
||||||
#include <linux/jiffies.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/printk.h> /* printk */
|
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
|
||||||
#include <uapi/linux/stat.h> /* S_IRUSR */
|
|
||||||
|
|
||||||
#define NAME "lkmc_character_device"
|
#define NAME "lkmc_character_device"
|
||||||
|
|
||||||
static int major;
|
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;
|
seq_printf(m, "abcd");
|
||||||
char kbuf[] = {'a', 'b', 'c', 'd'};
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = 0;
|
static int open(struct inode *inode, struct file *file)
|
||||||
if (*off == 0) {
|
{
|
||||||
if (copy_to_user(buf, kbuf, sizeof(kbuf))) {
|
return single_open(file, show, NULL);
|
||||||
ret = -EFAULT;
|
|
||||||
} else {
|
|
||||||
ret = sizeof(kbuf);
|
|
||||||
*off = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations fops = {
|
static const struct file_operations fops = {
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.open = open,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.read = read,
|
.read = seq_read,
|
||||||
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int myinit(void)
|
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;
|
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);
|
return single_open(file, show, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -ex
|
||||||
insmod /character_device.ko
|
insmod /character_device.ko
|
||||||
/mknoddev.sh lkmc_character_device
|
/mknoddev.sh lkmc_character_device
|
||||||
cat /dev/lkmc_character_device
|
[ "$(cat /dev/lkmc_character_device)" = 'abcd' ]
|
||||||
# => abcd
|
|
||||||
rm /dev/lkmc_character_device
|
rm /dev/lkmc_character_device
|
||||||
rmmod 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