[英]How to create a device node from the init_module code of a Linux kernel module?
I am writing a module for the linux kernel and I want to create some device nodes in the init function 我正在为linux内核编写一个模块,我想在init函数中创建一些设备节点
int init_module(void)
{
Major = register_chrdev(0, DEVICE_NAME, &fops);
// Now I want to create device nodes with the returned major number
}
I also want the kernel to assign a minor number for my first node, and then I will assign the other nodes' minor numbers by myself. 我还希望内核为我的第一个节点分配一个次要编号,然后我将自己分配其他节点的次要编号。
How can I do this in the code. 我怎么能在代码中执行此操作。 I dont want to create devices from the shell using mknod
我不想使用mknod从shell创建设备
To have more control over the device numbers and the device creation you could do the following steps (instead of register_chrdev()
): 要更好地控制设备编号和设备创建,您可以执行以下步骤(而不是
register_chrdev()
):
alloc_chrdev_region()
to get a major number and a range of minor numbers to work with. alloc_chrdev_region()
以获取要使用的主要数字和一系列次要数字。 class_create()
. class_create()
为您的设备创建设备类。 cdev_init()
and cdev_add()
to add the character device to the system. cdev_init()
和cdev_add()
以将字符设备添加到系统。 device_create()
. device_create()
。 As a result, among other things, Udev will create device nodes for your devices. mknod
or the like. mknod
等。 device_create()
also allows you to control the names of the devices. device_create()
还允许您控制设备的名称。 There are probably many examples of this on the Net, one of them is here . 网上可能有很多这样的例子, 其中一个在这里 。
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;
}
Minimal runnable example 最小的可运行示例
Minimized from other answers. 最小化其他答案。 GitHub upstream with test setup.
GitHub上游测试设置。
#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");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.