You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派3 Model B执行make命令编译内核模块报错求助

解决树莓派内核模块编译错误及代码修正方案

一、先解决make编译报错问题

错误核心是/lib/modules/6.1.21-v7+/build目录不存在,这是因为树莓派默认未安装对应内核版本的头文件,按以下步骤修复:

  • 更新系统包列表:
    sudo apt update
    
  • 安装匹配当前内核的头文件:
    sudo apt install raspberrypi-kernel-headers
    
    该包会自动适配你当前运行的6.1.21-v7+内核,安装后/lib/modules/$(uname -r)/build会自动指向正确的头文件目录。
  • 若安装后仍报错,手动创建软链接补全路径:
    sudo ln -s /usr/src/linux-headers-6.1.21-v7+ /lib/modules/6.1.21-v7+/build
    

二、代码中的致命问题(编译通过后必现错误)

你的代码意图是拦截鼠标事件,但存在多处不符合内核模块规范的问题,必须修正才能正常工作:

  1. 重复定义struct input_handler
    <linux/input.h>中已经定义了该结构体,删除代码中重复定义的这段:
    static struct input_handler {
        void (*event)(struct input_handler *, void *, struct input_event *);
        const char *name;
        const struct input_device_id *id_table;
    };
    
  2. input_get_handler参数错误
    该函数接收的是struct input_device指针,而非设备名,需先通过设备名获取设备指针:
    struct input_dev *dev = input_find_device_by_name(NULL, "mouse0");
    if (!dev) {
        printk(KERN_ERR "Failed to find mouse0\n");
        return -ENODEV;
    }
    old_handler = dev->handler;
    input_get_handler(old_handler);
    
  3. 必须启用MODULE_LICENSE
    注释掉该行会导致内核拒绝加载模块,取消注释:
    MODULE_LICENSE("GPL");
    
  4. 事件拦截逻辑错误
    返回0会让事件继续向下传递,达不到拦截效果,修改返回值:
    static int block_mouse_event(struct input_handler *handler, void *data, struct input_event *event)
    {
        // 返回非0值阻止事件传递
        return -ENODEV;
    }
    
  5. id_table不能为空
    需定义匹配鼠标设备的规则,否则自定义handler无法捕获鼠标事件:
    static const struct input_device_id block_mouse_ids[] = {
        {
            .evbit = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL),
            .keybit = BIT_MASK(BTN_MOUSE),
        },
        { } // 终止项
    };
    MODULE_DEVICE_TABLE(input, block_mouse_ids);
    
    同时在block_handler中设置.id_table = block_mouse_ids,

三、修正后的完整代码

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/input.h>

static struct input_handler *old_handler;
static struct input_dev *mouse_dev;

static int block_mouse_event(struct input_handler *handler, void *data, struct input_event *event)
{
    // 拦截鼠标输入事件,阻止事件传递
    return -ENODEV;
}

static const struct input_device_id block_mouse_ids[] = {
    {
        .evbit = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL),
        .keybit = BIT_MASK(BTN_MOUSE),
    },
    { }
};
MODULE_DEVICE_TABLE(input, block_mouse_ids);

static struct input_handler block_handler = {
    .event = block_mouse_event,
    .name = "block_mouse_handler",
    .id_table = block_mouse_ids,
};

static int __init mouse_block_init(void)
{
    printk(KERN_INFO "Mouse block module initialized\n");

    // 查找mouse0设备
    mouse_dev = input_find_device_by_name(NULL, "mouse0");
    if (!mouse_dev) {
        printk(KERN_ERR "Failed to locate mouse0 device\n");
        return -ENODEV;
    }

    // 保存原handler
    old_handler = mouse_dev->handler;
    if (old_handler) {
        input_get_handler(old_handler);
    }

    // 注册自定义handler
    return input_register_handler(&block_handler);
}

static void __exit mouse_block_exit(void)
{
    printk(KERN_INFO "Mouse block module removed\n");

    // 注销handler
    input_unregister_handler(&block_handler);

    // 释放原handler
    if (old_handler) {
        input_put_handler(old_handler);
        old_handler = NULL;
    }

    if (mouse_dev) {
        input_put_device(mouse_dev);
        mouse_dev = NULL;
    }
}

module_init(mouse_block_init);
module_exit(mouse_block_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Mouse Event Block Module");
MODULE_AUTHOR("Your Name");

内容的提问来源于stack exchange,提问作者Jasmine58850_01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:57:40