Device Creation
Linux character devices are registered using alloc_chrdev_region(), which allocates a major number and creates device files in /dev. This function is essential for exposing custom hardware or virtual devices to user-space applications. The process involves allocating a device number range, registering the device, and ensuring proper cleanup on module removal.
Allocating a Device Number¶
The alloc_chrdev_region() function reserves a range of device numbers for your module. It takes four parameters:
- dev: A pointer to a dev_t variable where the allocated device number is stored.
- first_minor: The first minor number in the range (set to 0 for automatic assignment).
- num: The number of minor numbers to allocate.
- name: A string identifier for the device (used to create /dev/name entries).
Example:
dev_t dev;
int result = alloc_chrdev_region(&dev, 0, 1, "my_char_dev");
if (result < 0) {
printk(KERN_ERR "Failed to allocate device number\n");
return result;
}
Creating Device Files¶
The kernel automatically creates device files in /dev using the name parameter. For example, if name is "my_char_dev", the file /dev/my_char_dev is created. The major number is derived from dev using MAJOR(dev).
Unregistering the Device¶
When the module is removed, unregister_chrdev_region() frees the allocated device numbers:
void cleanup_module(void) {
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device unregistered\n");
}
Example Code¶
Here’s a minimal module demonstrating the process:
#include <linux/fs.h>
#include <linux/module.h>
static dev_t dev;
static int __init my_char_dev_init(void) {
int result = alloc_chrdev_region(&dev, 0, 1, "my_char_dev");
if (result < 0) {
printk(KERN_ERR "Allocation failed\n");
return result;
}
printk(KERN_INFO "Device registered (major: %d)\n", MAJOR(dev));
return 0;
}
static void __exit my_char_dev_exit(void) {
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device unregistered\n");
}
module_init(my_char_dev_init);
module_exit(my_char_dev_exit);
Key takeaways¶
alloc_chrdev_region()allocates a major number and creates/deventries automatically.- Always check for allocation errors and handle cleanup in
exitfunctions. - The
nameparameter determines the device file name in/dev. - Device numbers are managed as
dev_tvalues, combining major and minor components. - Manual
mknodcalls are unnecessary when usingalloc_chrdev_region().