root@T:/media/sf_D_DRIVE/kmodule/13_char_dev# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
root@T:/media/sf_D_DRIVE/kmodule/13_char_dev#
my_char_dev.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cdev.h>
#define TAG "HELLO# "
#define COUNT 10
static dev_t my_devt;
static struct class *my_class;
static struct cdev *my_cdev;
struct device *my_device[COUNT];
static int my_cdev_open(struct inode *inode, struct file *file)
{
printk(TAG "%s called\n", __func__);
return 0;
}
static int my_cdev_release(struct inode *inode, struct file *file)
{
printk(TAG "%s called\n", __func__);
return 0;
}
static const struct file_operations my_cdev_fops = {
.owner = THIS_MODULE,
.open = my_cdev_open,
.release = my_cdev_release,
};
static int my_char_dev_init(void)
{
int err;
int i;
printk(TAG "%s called\n", __func__);
/* create /sys/class/my_class */
my_class = class_create("my_class");
my_cdev = cdev_alloc();
cdev_init(my_cdev, &my_cdev_fops);
err = alloc_chrdev_region(&my_devt, 0, COUNT, "dont'care");
err = cdev_add(my_cdev, my_devt, COUNT);
/* create /sys/dev/char/major:minor */
for(i = 0; i < COUNT; i++)
{
my_device[i] = device_create(my_class, NULL, my_devt + i, NULL, "my_device_name%d", i);
}
return err;
}
static void my_char_dev_exit(void)
{
int i;
printk(TAG "%s called\n", __func__);
for(i = 0; i < COUNT; i++)
{
device_destroy(my_class, my_devt + i);
}
unregister_chrdev_region(my_devt, COUNT);
cdev_del(my_cdev);
class_destroy(my_class);
}
module_init(my_char_dev_init);
module_exit(my_char_dev_exit);
MODULE_LICENSE("GPL");
效果
<完>