*.o转换为*.ko的问题

博客提供了ChinaUnix论坛的一个链接,地址为http://bbs.chinaunix.net/thread-2184190-1-1.html 。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我新建了文件夹并在其中仅放入my_char_dev.c和Makefile文件分别如下:#include <linux/module.h> // 内核模块基础支持 #include <linux/kernel.h> // 内核打印函数printk #include <linux/fs.h> // 文件操作结构体file_operations #include <linux/cdev.h> // 字符设备结构体cdev #include <linux/uaccess.h> // 用户空间内存访问函数 #include <linux/device.h> // 设备类支持 #define DEVICE_NAME "my_char_dev" // 设备名称 #define CLASS_NAME "my_class" // 设备类名称 MODULE_LICENSE("GPL"); // 模块许可证 MODULE_AUTHOR("Your Name"); // 模块作者 MODULE_DESCRIPTION("Simple Char Driver with Case Control"); // 模块描述 // 设备结构体包含所有设备相关信息 struct my_device { struct cdev cdev; // 字符设备结构 struct class *class; // 设备类指针 struct device *device; // 设备实例 int cap_enabled; // 大写转换标志 (1=启用) } my_dev; // 模块参数声明 static int cap_param = 0; // 默认关闭大写转换 module_param(cap_param, int, S_IRUGO); // 定义模块参数 MODULE_PARM_DESC(cap_param, "Enable uppercase conversion (1=enable)"); // 参数描述 // 设备打开函数 static int dev_open(struct inode *inode, struct file *file) { printk(KERN_INFO "my_char_dev: Device opened\n"); return 0; } // 设备释放函数 static int dev_release(struct inode *inode, struct file *file) { printk(KERN_INFO "my_char_dev: Device closed\n"); return 0; } // 设备写入函数 (核心功能) static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { char kernel_buf[256]; // 内核缓冲区 int i; // 检查写入长度是否超过缓冲区大小 if (count > sizeof(kernel_buf) - 1) { printk(KERN_WARNING "my_char_dev: Write size too large\n"); return -EFAULT; } // 从用户空间复制数据到内核空间 if (copy_from_user(kernel_buf, buf, count)) { printk(KERN_ERR "my_char_dev: Failed to copy from user\n"); return -EFAULT; } kernel_buf[count] = '\0'; // 确保字符串终止 // 根据cap_enabled标志进行大写转换 if (my_dev.cap_enabled) { for (i = 0; kernel_buf[i]; i++) { if (kernel_buf[i] >= 'a' && kernel_buf[i] <= 'z') { kernel_buf[i] -= 32; // 小写转大写 } } } // 打印处理后的内容 printk(KERN_INFO "my_char_dev: Received: %s\n", kernel_buf); return count; // 返回实际写入的字节数 } // 文件操作结构体定义 static struct file_operations fops = { .owner = THIS_MODULE, .open = dev_open, .release = dev_release, .write = dev_write, }; // 模块初始化函数 static int __init char_dev_init(void) { dev_t devno; int result; printk(KERN_INFO "my_char_dev: Initializing module\n"); // 1. 分配设备号 if ((result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME)) < 0) { printk(KERN_ERR "my_char_dev: Failed to allocate device number\n"); return result; } // 2. 初始化字符设备 cdev_init(&my_dev.cdev, &fops); my_dev.cdev.owner = THIS_MODULE; // 3. 添加字符设备到系统 if ((result = cdev_add(&my_dev.cdev, devno, 1)) < 0) { unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to add cdev\n"); return result; } // 4. 创建设备类 my_dev.class = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(my_dev.class)) { cdev_del(&my_dev.cdev); unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to create class\n"); return PTR_ERR(my_dev.class); } // 5. 创建设备节点 (/dev/my_char_dev) my_dev.device = device_create(my_dev.class, NULL, devno, NULL, DEVICE_NAME); if (IS_ERR(my_dev.device)) { class_destroy(my_dev.class); cdev_del(&my_dev.cdev); unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to create device\n"); return PTR_ERR(my_dev.device); } // 6. 应用模块参数 my_dev.cap_enabled = cap_param; printk(KERN_INFO "my_char_dev: Module loaded. Uppercase conversion: %s\n", my_dev.cap_enabled ? "ENABLED" : "DISABLED"); return 0; } // 模块退出函数 static void __exit char_dev_exit(void) { dev_t devno = my_dev.cdev.dev; // 1. 销毁设备节点 device_destroy(my_dev.class, devno); // 2. 销毁设备类 class_destroy(my_dev.class); // 3. 删除字符设备 cdev_del(&my_dev.cdev); // 4. 释放设备号 unregister_chrdev_region(devno, 1); printk(KERN_INFO "my_char_dev: Module unloaded\n"); } // 注册初始化和退出函数 module_init(char_dev_init); module_exit(char_dev_exit); obj-m := my_char_dev.o # 使用 := 替代 += 避免污染 all: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean rm -f *.o *.ko *.mod* .*.cmd .*.d modules.order Module.symvers——运行时报错如下:linzihao@linzihao-virtual-machine:~/Code/test/coursework2/work4$ make clean make: *** 没有规则可制作目标“clean”。 停止。——这是什么原因
最新发布
08-08
// 必要的内核头文件 #include <linux/module.h> // 内核模块基础支持 #include <linux/kernel.h> // 内核打印函数printk #include <linux/fs.h> // 文件操作结构体file_operations #include <linux/cdev.h> // 字符设备结构体cdev #include <linux/uaccess.h> // 用户空间内存访问函数 #include <linux/device.h> // 设备类支持 #define DEVICE_NAME "my_char_dev" // 设备名称 #define CLASS_NAME "my_class" // 设备类名称 MODULE_LICENSE("GPL"); // 模块许可证 MODULE_AUTHOR("Your Name"); // 模块作者 MODULE_DESCRIPTION("Simple Char Driver with Case Control"); // 模块描述 // 设备结构体包含所有设备相关信息 struct my_device { struct cdev cdev; // 字符设备结构 struct class *class; // 设备类指针 struct device *device; // 设备实例 int cap_enabled; // 大写转换标志 (1=启用) } my_dev; // 模块参数声明 static int cap_param = 0; // 默认关闭大写转换 module_param(cap_param, int, S_IRUGO); // 定义模块参数 MODULE_PARM_DESC(cap_param, "Enable uppercase conversion (1=enable)"); // 参数描述 // 设备打开函数 static int dev_open(struct inode *inode, struct file *file) { printk(KERN_INFO "my_char_dev: Device opened\n"); return 0; } // 设备释放函数 static int dev_release(struct inode *inode, struct file *file) { printk(KERN_INFO "my_char_dev: Device closed\n"); return 0; } // 设备写入函数 (核心功能) static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { char kernel_buf[256]; // 内核缓冲区 int i; // 检查写入长度是否超过缓冲区大小 if (count > sizeof(kernel_buf) - 1) { printk(KERN_WARNING "my_char_dev: Write size too large\n"); return -EFAULT; } // 从用户空间复制数据到内核空间 if (copy_from_user(kernel_buf, buf, count)) { printk(KERN_ERR "my_char_dev: Failed to copy from user\n"); return -EFAULT; } kernel_buf[count] = '\0'; // 确保字符串终止 // 根据cap_enabled标志进行大写转换 if (my_dev.cap_enabled) { for (i = 0; kernel_buf[i]; i++) { if (kernel_buf[i] >= 'a' && kernel_buf[i] <= 'z') { kernel_buf[i] -= 32; // 小写转大写 } } } // 打印处理后的内容 printk(KERN_INFO "my_char_dev: Received: %s\n", kernel_buf); return count; // 返回实际写入的字节数 } // 文件操作结构体定义 static struct file_operations fops = { .owner = THIS_MODULE, .open = dev_open, .release = dev_release, .write = dev_write, }; // 模块初始化函数 static int __init char_dev_init(void) { dev_t devno; int result; printk(KERN_INFO "my_char_dev: Initializing module\n"); // 1. 分配设备号 if ((result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME)) < 0) { printk(KERN_ERR "my_char_dev: Failed to allocate device number\n"); return result; } // 2. 初始化字符设备 cdev_init(&my_dev.cdev, &fops); my_dev.cdev.owner = THIS_MODULE; // 3. 添加字符设备到系统 if ((result = cdev_add(&my_dev.cdev, devno, 1)) < 0) { unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to add cdev\n"); return result; } // 4. 创建设备类 my_dev.class = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(my_dev.class)) { cdev_del(&my_dev.cdev); unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to create class\n"); return PTR_ERR(my_dev.class); } // 5. 创建设备节点 (/dev/my_char_dev) my_dev.device = device_create(my_dev.class, NULL, devno, NULL, DEVICE_NAME); if (IS_ERR(my_dev.device)) { class_destroy(my_dev.class); cdev_del(&my_dev.cdev); unregister_chrdev_region(devno, 1); printk(KERN_ERR "my_char_dev: Failed to create device\n"); return PTR_ERR(my_dev.device); } // 6. 应用模块参数 my_dev.cap_enabled = cap_param; printk(KERN_INFO "my_char_dev: Module loaded. Uppercase conversion: %s\n", my_dev.cap_enabled ? "ENABLED" : "DISABLED"); return 0; } // 模块退出函数 static void __exit char_dev_exit(void) { dev_t devno = my_dev.cdev.dev; // 1. 销毁设备节点 device_destroy(my_dev.class, devno); // 2. 销毁设备类 class_destroy(my_dev.class); // 3. 删除字符设备 cdev_del(&my_dev.cdev); // 4. 释放设备号 unregister_chrdev_region(devno, 1); printk(KERN_INFO "my_char_dev: Module unloaded\n"); } // 注册初始化和退出函数 module_init(char_dev_init); module_exit(char_dev_exit); ——这个是我写的内核模块,下面是makefile文件obj-m += my_char_dev.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean——我在make时出现以下报错:linzihao@linzihao-virtual-machine:~/Code/test/coursework2/work3$ * History restored linzihao@linzihao-virtual-machine:~/Code/test/coursework2/work3$ make make -C /lib/modules/4.15.0-213-generic/build/ M=/home/linzihao/Code/test/coursework2/work3 make[1]: 进入目录“/usr/src/linux-headers-4.15.0-213-generic” make[2]: *** 没有规则可制作目标“/home/linzihao/Code/test/coursework2/work3/hello.c”,由“/home/linzihao/Code/test/coursework2/work3/hello.o” 需求。 停止。 Makefile:1596: recipe for target '_module_/home/linzihao/Code/test/coursework2/work3' failed make[1]: *** [_module_/home/linzihao/Code/test/coursework2/work3] Error 2 make[1]: 离开目录“/usr/src/linux-headers-4.15.0-213-generic” Makefile:7: recipe for target 'all' failed make: *** [all] Error 2 linzihao@linzihao-virtual-machine:~/Code/test/coursework2/work3$ make clean rm -rf *.o *.mod.c *.mod.o *.ko *.symvers *.order *.a——执行maike clean也无法解决,试分析出是什么问题并解决
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值