|
|
@@ -0,0 +1,88 @@
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/init.h>
|
|
|
+#include <linux/fs.h> // 包含 file_operations 和 register_chrdev 函数
|
|
|
+#include <linux/cdev.h> // 包含 cdev 相关结构和函数
|
|
|
+
|
|
|
+#define DEVICE_NAME "charDevice2"
|
|
|
+#define CLASS_NAME "my_char_class2"
|
|
|
+static int majorNumber; // 设备号
|
|
|
+static struct class* myCharClass = NULL; // 设备类
|
|
|
+// 文件操作函数声明
|
|
|
+static int dev_open(struct inode *inode, struct file *file);
|
|
|
+static int dev_release(struct inode *inode, struct file *file);
|
|
|
+static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos);
|
|
|
+static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
|
|
|
+
|
|
|
+// 文件操作结构
|
|
|
+static struct file_operations fops = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .open = dev_open,
|
|
|
+ .release = dev_release,
|
|
|
+ .read = dev_read,
|
|
|
+ .write = dev_write,
|
|
|
+};
|
|
|
+
|
|
|
+// 文件操作函数的实现
|
|
|
+static int dev_open(struct inode *inode, struct file *file) {
|
|
|
+ pr_info("Device opened\n");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int dev_release(struct inode *inode, struct file *file) {
|
|
|
+ pr_info("Device closed\n");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
|
|
|
+ pr_info("Reading from device\n");
|
|
|
+ return 0; // 假设返回 0 表示读到文件结尾
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
|
|
|
+ pr_info("Writing to device\n");
|
|
|
+ return count; // 返回写入的字节数
|
|
|
+}
|
|
|
+
|
|
|
+static int __init helloworld_init(void) {
|
|
|
+ int retvalue;
|
|
|
+
|
|
|
+
|
|
|
+// 自动申请设备号
|
|
|
+ majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
|
|
|
+ if (majorNumber < 0) {
|
|
|
+ printk(KERN_ALERT "my_char_device failed to register a major number\n");
|
|
|
+ return majorNumber;
|
|
|
+ }
|
|
|
+ printk(KERN_INFO "my_char_device: registered correctly with major number %d\n", majorNumber);
|
|
|
+
|
|
|
+ // 创建设备类
|
|
|
+ myCharClass = class_create(THIS_MODULE, CLASS_NAME);
|
|
|
+ if (IS_ERR(myCharClass)) {
|
|
|
+ unregister_chrdev(majorNumber, DEVICE_NAME);
|
|
|
+ printk(KERN_ALERT "Failed to register device class\n");
|
|
|
+ return PTR_ERR(myCharClass);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建设备
|
|
|
+ device_create(myCharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
|
|
|
+ printk(KERN_INFO "my_char_device: device class created correctly\n");
|
|
|
+
|
|
|
+ pr_info("Hello world initialization!\n");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void __exit helloworld_exit(void) {
|
|
|
+ device_destroy(myCharClass, MKDEV(majorNumber, 0)); // 删除设备
|
|
|
+ class_unregister(myCharClass); // 取消设备类注册
|
|
|
+ class_destroy(myCharClass); // 销毁设备类
|
|
|
+ // 注销字符设备驱动
|
|
|
+ unregister_chrdev(200, DEVICE_NAME);
|
|
|
+ pr_info("Hello world exit\n");
|
|
|
+}
|
|
|
+
|
|
|
+module_init(helloworld_init);
|
|
|
+module_exit(helloworld_exit);
|
|
|
+
|
|
|
+MODULE_LICENSE("GPL");
|
|
|
+MODULE_AUTHOR("John Madieu <john.madieu@gmail.com>");
|
|
|
+MODULE_DESCRIPTION("Linux kernel module skeleton");
|