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()
):
- Call
alloc_chrdev_region()
to get a major number and a range of minor numbers to work with. - Create device class for your devices with
class_create()
. - For each device, call
cdev_init()
andcdev_add()
to add the character device to the system. - For each device, call
device_create()
. As a result, among other things, Udev will create device nodes for your devices. No need formknod
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
What Is the Linux Equivalent to Dos Pause
How to Kill All Linux Processes That Are Older Than a Certain Age
How Clear and Invalidate Arm V7 Processor Cache from User Mode on Linux 2.6.35
Git Status Ignore Line Endings/Identical Files/Windows & Linux Environment/Dropbox/Meld
Find Matching Text and Replace Next Line
How to Make Bash Treat Undefined Variables as Errors
Setting Default Permissions for Newly Created Files and Sub-Directories Under a Directory in Linux
Linux: Command to Open Url in Default Browser
/Usr/Bin/Ld: Cannot Find -Llapack
Linux: Remove File Extensions for Multiple Files
How to Trim White Space from a Variable in Awk
How to Edit /Etc/Sudoers from a Script
Why Do Shells Ignore Sigint and Sigquit in Backgrounded Processes
Rsync Copy Over Only Certain Types of Files Using Include Option