insmod出现loading out-of-tree module taints kernel

其实这句话已经表达了错误的原因了:加载树外模块污染内核,意思是我们加载的驱动中需要的设备树节点在当前设备树文件中未找到。

我们需要检查驱动文件中of_match_table数组中的compatible属性是否在设备树中有对应节点

static const struct of_device_id of_match_buttons[] =
{
	{.compatible = "jz2440_button", .data= NULL}, //匹配名字为jz2440_button的子节点
	{/* sentinel */},

};


static struct platform_driver buttons_drv =
{
	.probe = buttons_probe,
	.remove = buttons_remove,
	.driver ={
		.name = "myButtons",
		.of_match_table = of_match_buttons, //表示匹配哪些设备树节点,匹配成功后调用probe函数
	}
};

 

loading out-of-tree module taints kernel由/kernel/module.ccheck_modinfo()打印(内核版本linux-4.19-rc3)

具体的调用过程:

在命令行中使用insmod加载驱动,会调用到busybox中的相关函数。(位于busybox/modutils/ insmod.c)

insmod_main
|
--> bb_init_module
    |
    --> init_module

init_module是定义在busybox/modutils/modutils.c的宏

#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)

最终会调用到对应内核层的 sys_init_module 函数。(/kernel/module.c

SYSCALL_DEFINE3(init_module,....)
     load_module()
         layout_and_allocate() //找出模块布局,分配所有内存
              check_modinfo() //校验模块信息
                   	if (!get_modinfo(info, "intree")) {
                		if (!test_taint(TAINT_OOT_MODULE))
			                pr_warn("%s: loading out-of-tree module taints kernel.\n",
				            mod->name);
		                    add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
	                 }

 

最近调一个spi驱动的时候刚好也遇到了这个问题:

打印了loading out-of-tree module taints kernel,但是probe函数也正常运行了,然后驱动也正常运行,感觉之前写下来的结论哪里不对[狗头]。

<think>好的,我现在需要帮助用户了解如何在Linux Kernel 4.19中配置GPIO模式。首先,我需要回顾一下自己关于Linux内核GPIO子系统的知识。GPIO(通用输入输出)在嵌入式系统中非常重要,用于控制硬件设备。 用户提到的是Kernel 4.19,这个版本的内核可能使用较新的GPIO接口,比如基于描述符的API,而不是旧的基于编号的方法。我需要确认这一点,避免提供过时的信息。 首先,配置GPIO通常包括几个步骤:申请GPIO、设置方向(输入或输出)、读写值、释放GPIO。在设备树(Device Tree)中定义GPIO是常见做法,特别是在使用设备树的内核版本中。所以,用户可能需要了解如何在设备树中添加GPIO节点,然后在驱动代码中获取这些GPIO。 另外,用户可能需要知道如何通过sysfs接口进行配置,虽然sysfs在较新的内核中可能被逐步淘汰,转而使用chardev(比如libgpiod)。但如果是内核配置,可能更关注驱动层面的代码,而不是用户空间的工具。 接下来,我需要考虑用户可能的场景。用户可能是在开发一个内核驱动,需要控制某个GPIO引脚,比如控制LED或读取按钮状态。因此,回答需要涵盖设备树配置、驱动代码中的GPIO操作,以及必要的头文件和API函数。 同时,需要确保示例代码符合内核4.19的API。例如,使用gpiod_get()而不是gpio_request(),因为新的API更推荐基于描述符的函数。此外,错误处理也是关键,比如检查返回值,正确释放资源。 可能的问题点包括:设备树中GPIO引脚的正确语法,如何在代码中引用这些引脚,以及编译和加载模块的步骤。用户可能还需要知道如何验证配置是否生效,比如通过GPIO的状态变化或使用示波器测量信号。 另外,需要提醒用户注意GPIO编号和引脚名称的对应关系,不同硬件平台可能有不同的映射方式,参考具体的板级支持包(BSP)文档很重要。例如,树莓派和BeagleBone Black的GPIO编号方式不同。 最后,应该生成相关问题,帮助用户深入理解,比如如何调试GPIO配置,如何处理多个GPIO,或者如何在中断上下文中使用GPIO。这些相关问题可以引导用户进一步探索。</think>### Linux Kernel 4.19 GPIO模式配置教程 在Linux Kernel 4.19中配置GPIO模式主要通过设备树(Device Tree)和GPIO子系统API实现,以下是详细步骤: --- #### 一、设备树配置 1. **定位GPIO控制器节点** 在`.dts`文件中查找类似内容: ```dts gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7795"; reg = <0xe6050000 0x50>; #gpio-cells = <2>; }; ``` 2. **定义GPIO使用属性** 在需要使用GPIO的设备节点中添加: ```dts my_device { compatible = "custom,my-device"; led-gpio = <&gpio0 15 GPIO_ACTIVE_HIGH>; // GPIO0组第15引脚,高电平有效 }; ``` --- #### 二、驱动代码实现 ```c #include <linux/gpio/consumer.h> // 新版GPIO API头文件 struct gpio_desc *gpio_led; // GPIO描述符指针 // 初始化GPIO static int __init my_driver_init(void) { // 获取设备树中定义的GPIO gpio_led = gpiod_get(&pdev->dev, "led", GPIOD_OUT_LOW); if (IS_ERR(gpio_led)) { pr_err("无法获取GPIO\n"); return PTR_ERR(gpio_led); } // 设置GPIO电平 gpiod_set_value(gpio_led, 1); return 0; } // 释放资源 static void __exit my_driver_exit(void) { gpiod_put(gpio_led); } module_init(my_driver_init); module_exit(my_driver_exit); ``` --- #### 三、关键API说明 | API函数 | 功能描述 | |-----------------------|---------------------------------| | `gpiod_get()` | 获取GPIO描述符 | | `gpiod_direction_output()` | 设置为输出模式 | | `gpiod_set_value()` | 设置输出电平 | | `gpiod_get_value()` | 读取输入电平(输入模式时使用) | --- #### 四、验证配置 1. 编译驱动后插入内核: ```bash insmod my_driver.ko ``` 2. 通过sysfs检查GPIO状态: ```bash cat /sys/kernel/debug/gpio # 查看GPIO使用状态 ``` 3. 使用示波器测量实际引脚电平变化 --- #### 五、注意事项 1. 新旧API差异:Kernel 4.19已废弃`gpio_request()`,推荐使用基于描述符的API[^1] 2. 引脚复用:需确保GPIO未被其他功能(如I2C、SPI)占用 3. 电平标准:注意硬件设计中的电压匹配(3.3V/1.8V)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值