Comment créer un nœud de périphérique à partir du code du module init d'un module du noyau Linux?
J'écris un module pour le noyau linux et je veux créer des nœuds de périphérique dans la fonction init
int init_module(void)
{
Major = register_chrdev(0, DEVICE_NAME, &fops);
// Now I want to create device nodes with the returned major number
}
Je veux aussi que le noyau attribue un nombre mineur à mon premier nœud, puis j'attribuerai les numéros mineurs des autres nœuds par moi-même.
Comment puis-je faire cela dans le code. Je ne veux pas créer de périphériques à partir du shell en utilisant mknod
41
demandé sur
Ciro Santilli 新疆改造中心 六四事件 法轮功
2011-05-12 01:03:09
3 réponses
Pour avoir plus de contrôle sur les numéros de périphérique et la création de périphérique, vous pouvez effectuer les étapes suivantes (au lieu de register_chrdev()
):
- appelez
alloc_chrdev_region()
pour obtenir un nombre majeur et une plage de nombres mineurs avec lesquels travailler. - créez une classe de périphérique pour vos périphériques avec
class_create()
. - , Pour chaque appareil, appelez -
cdev_init()
etcdev_add()
pour ajouter le caractère périphérique du système. - , Pour chaque appareil, appelez -
device_create()
. En conséquence, entre autres choses, Udev créera des nœuds de périphérique pour vos appareils. Pas besoin demknod
ou similaire.device_create()
vous permet également de contrôler les noms de périphériques.
, Il existe probablement de nombreux exemples sur le Net, l'un d'eux est ici.
68
répondu
Eugene
2015-06-10 07:53:34
static int __init ofcd_init(void) /* Constructor */
{
printk(KERN_INFO "Welcome!");
if (alloc_chrdev_region(&first, 0, 1, "char_dev") < 0) //$cat /proc/devices
{
return -1;
}
if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL) //$ls /sys/class
{
unregister_chrdev_region(first, 1);
return -1;
}
if (device_create(cl, NULL, first, NULL, "mynull") == NULL) //$ls /dev/
{
class_destroy(cl);
unregister_chrdev_region(first, 1);
return -1;
}
cdev_init(&c_dev, &fops);
if (cdev_add(&c_dev, first, 1) == -1)
{
device_destroy(cl, first);
class_destroy(cl);
unregister_chrdev_region(first, 1);
return -1;
}
return 0;
}
12
répondu
Edwin Jose
2013-09-03 14:24:04
Minimum praticable exemple
Réduit à partir d'autres réponses. GitHub amont avec configuration de test.
#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 void cleanup(int device_created)
{
if (device_created) {
device_destroy(myclass, major);
cdev_del(&mycdev);
}
if (myclass)
class_destroy(myclass);
if (major != -1)
unregister_chrdev_region(major, 1);
}
static int myinit(void)
{
int device_created = 0;
/* cat /proc/devices */
if (alloc_chrdev_region(&major, 0, 1, NAME "_proc") < 0)
goto error;
/* ls /sys/class */
if ((myclass = class_create(THIS_MODULE, NAME "_sys")) == NULL)
goto error;
/* ls /dev/ */
if (device_create(myclass, NULL, major, NULL, NAME "_dev") == NULL)
goto error;
device_created = 1;
cdev_init(&mycdev, &fops);
if (cdev_add(&mycdev, major, 1) == -1)
goto error;
return 0;
error:
cleanup(device_created);
return -1;
}
static void myexit(void)
{
cleanup(1);
}
module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");
5
répondu
Ciro Santilli 新疆改造中心 六四事件 法轮功
2017-08-06 12:03:49