Registering a Character Device
Before a character device can interact with the Linux kernel, you must register it so the kernel knows how to communicate with your driver. Registering a character device involves reserving a range of device numbers (major and minor), initializing a character device structure, and associating your driver's file operations with that device. This step is essential for allowing user-space programs to access your device through a node in the /dev directory.
char_reg_example.c
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/cdev.h> #define DEVICE_NAME "mychardev" static dev_t dev_num; // will hold the major and minor number static struct cdev my_cdev; static int __init mychar_init(void) { int result; // Allocate a range of char device numbers result = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); if (result < 0) { pr_err("Failed to allocate char device region\n"); return result; } // Initialize cdev structure and add it to kernel cdev_init(&my_cdev, NULL); // NULL for file_operations as placeholder my_cdev.owner = THIS_MODULE; result = cdev_add(&my_cdev, dev_num, 1); if (result < 0) { pr_err("Failed to add cdev\n"); unregister_chrdev_region(dev_num, 1); return result; } pr_info("Char device registered: major=%d minor=%d\n", MAJOR(dev_num), MINOR(dev_num)); return 0; } static void __exit mychar_exit(void) { cdev_del(&my_cdev); unregister_chrdev_region(dev_num, 1); pr_info("Char device unregistered\n"); } module_init(mychar_init); module_exit(mychar_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("Simple Character Device Registration Example");
When registering a character device, you must assign it a unique identifier so the kernel and user-space applications can reference it. This identifier consists of a major number, which identifies the driver associated with the device, and a minor number, which distinguishes between different devices or instances managed by the same driver. In the example above, the alloc_chrdev_region function dynamically allocates a major number and a range of minor numbers. The cdev_init function prepares the character device structure, and cdev_add registers it with the kernel. You can retrieve the assigned major and minor numbers using the MAJOR() and MINOR() macros, which are printed for reference.
char_unreg_example.c
1234567891011121314#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> static dev_t dev_num; static struct cdev my_cdev; static void __exit mychar_exit(void) { cdev_del(&my_cdev); unregister_chrdev_region(dev_num, 1); pr_info("Char device unregistered\n"); } module_exit(mychar_exit);
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
Fantastiskt!
Completion betyg förbättrat till 3.85
Registering a Character Device
Svep för att visa menyn
Before a character device can interact with the Linux kernel, you must register it so the kernel knows how to communicate with your driver. Registering a character device involves reserving a range of device numbers (major and minor), initializing a character device structure, and associating your driver's file operations with that device. This step is essential for allowing user-space programs to access your device through a node in the /dev directory.
char_reg_example.c
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/cdev.h> #define DEVICE_NAME "mychardev" static dev_t dev_num; // will hold the major and minor number static struct cdev my_cdev; static int __init mychar_init(void) { int result; // Allocate a range of char device numbers result = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); if (result < 0) { pr_err("Failed to allocate char device region\n"); return result; } // Initialize cdev structure and add it to kernel cdev_init(&my_cdev, NULL); // NULL for file_operations as placeholder my_cdev.owner = THIS_MODULE; result = cdev_add(&my_cdev, dev_num, 1); if (result < 0) { pr_err("Failed to add cdev\n"); unregister_chrdev_region(dev_num, 1); return result; } pr_info("Char device registered: major=%d minor=%d\n", MAJOR(dev_num), MINOR(dev_num)); return 0; } static void __exit mychar_exit(void) { cdev_del(&my_cdev); unregister_chrdev_region(dev_num, 1); pr_info("Char device unregistered\n"); } module_init(mychar_init); module_exit(mychar_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("Simple Character Device Registration Example");
When registering a character device, you must assign it a unique identifier so the kernel and user-space applications can reference it. This identifier consists of a major number, which identifies the driver associated with the device, and a minor number, which distinguishes between different devices or instances managed by the same driver. In the example above, the alloc_chrdev_region function dynamically allocates a major number and a range of minor numbers. The cdev_init function prepares the character device structure, and cdev_add registers it with the kernel. You can retrieve the assigned major and minor numbers using the MAJOR() and MINOR() macros, which are printed for reference.
char_unreg_example.c
1234567891011121314#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> static dev_t dev_num; static struct cdev my_cdev; static void __exit mychar_exit(void) { cdev_del(&my_cdev); unregister_chrdev_region(dev_num, 1); pr_info("Char device unregistered\n"); } module_exit(mychar_exit);
Tack för dina kommentarer!