How to Create a Device Node from the Init_Module Code of a Linux Kernel Module

How to create a device node from the init_module code of a Linux kernel module?

To have more control over the device numbers and the device creation you could do the following steps (instead of register_chrdev()):

  1. Call alloc_chrdev_region() to get a major number and a range of minor numbers to work with.
  2. Create device class for your devices with class_create().
  3. For each device, call cdev_init() and cdev_add() to add the character device to the system.
  4. For each device, call device_create(). As a result, among other things, Udev will create device nodes for your devices. No need for mknod or the like. device_create() also allows you to control the names of the devices.

There are probably many examples of this on the Net, one of them is here.

Can I call mknod from my kernel module?

No you can't use mknod and rm cli's from kernel space. These are bash commands. But other option exists to create and remove the device node file of your module from kernel space. In module init function you can use class_create() and then device_create() functions after doing registration for you device. After cdev_init() call you can use this two function for node file creation. Similarly you can use device_destroy() and class_destroy() functions in module_exit function to remove the node file.

Here is sample code that creates /dev/kmem in a char device init function:

int majorNum;
dev_t devNo; // Major and Minor device numbers combined into 32 bits
struct class *pClass; // class_create will set this

static int __init devkoInit(void) {
struct device *pDev;

// Register character device
majorNum = register_chrdev(0, "devko", &fileOps);
if (majorNum < 0) {
printk(KERN_ALERT "Could not register device: %d\n", majorNum);
return majorNum;
}
devNo = MKDEV(majorNum, 0); // Create a dev_t, 32 bit version of numbers

// Create /sys/class/kmem in preparation of creating /dev/kmem
pClass = class_create(THIS_MODULE, "kmem");
if (IS_ERR(pClass)) {
printk(KERN_WARNING "\ncan't create class");
unregister_chrdev_region(devNo, 1);
return -1;
}

// Create /dev/kmem for this char dev
if (IS_ERR(pDev = device_create(pClass, NULL, devNo, NULL, "kmem"))) {
printk(KERN_WARNING "devko.ko can't create device /dev/kmem\n");
class_destroy(pClass);
unregister_chrdev_region(devNo, 1);
return -1;
}
return 0;
} // end of devkoInit


static void __exit devkoExit(void) {
// Clean up after ourselves
device_destroy(pClass, devNo); // Remove the /dev/kmem
class_destroy(pClass); // Remove class /sys/class/kmem
unregister_chrdev(majorNum, DEVICE_NAME); // Unregister the device
} // end of devkoExit

using udev rules create and remove device node on a kernel module load and unload

Explored the udev rules in detail and with the help of udevadm tool I am able to derive the following udev rules, my kernel module name is "amdtPwrProf".

On ACTION=="add" the device node is created and on ACTION=="remove" that device node is removed.

 # Create the device file when the module is inserted.

SUBSYSTEM=="module", ACTION=="add", KERNEL=="amdtPwrProf", RUN+="/opt/codexl/amdtPwrProf_mknod.sh"


# Remove the device file when the module is removed.

SUBSYSTEM=="module", ACTION=="remove", KERNEL=="amdtPwrProf", RUN+="/bin/rm /dev/amdtPwrProf"

The contents of script "amdtPwrProf_mknod.sh" are,

mknod /dev/amdtPwrProf -m 666 c `cat /proc/amdtPwrProf/device` 0

Write to proc in a kernel module which uses also a character device

As Tsyvarev mentioned use different file_operations

static struct proc_dir_entry *procfs;

static const struct file_operations proc_fops = {
.owner = THIS_MODULE,
.open = open_proc_fn,
.read = read_proc_fn,
};

static const struct file_operations char_fops = {
.owner = THIS_MODULE,
.open = open_char_fn,
.read = read_char_fn,
.write = write_char_fn,
};


int __init init_mod (void) {
procfs = proc_create("filename", 0, NULL, &proc_fops);
if(!proc)
return -1;
<Register char device with &char_fops >
return 0;
}


Related Topics



Leave a reply



Submit