我正在努力让更现代的 Linux 在单板计算机上运行,原来的公司已经倒闭,但硬件得到了开源社区的大力支持。我取得了很大的进展,但我遇到了一个问题,即为特定设备加载了错误的驱动程序模块。
平台是 Allwinner R8(与 Allwinner A13 相同),设备是电阻式触摸屏。发行版是 ARM 的 Slackware-current,这意味着没有 systemd,但它确实使用 eudev。我从源代码编译了内核 5.2.0-rc6,因为我想尝试 Mali lima 驱动程序,并且需要一些发行版中未包含的模块。设备树中的相关部分如下。
u-boot/arch/arm/dts/sun5i.dtsi:
587 rtp: rtp@1c25000 {
588 compatible = "allwinner,sun5i-a13-ts";
589 reg = <0x01c25000 0x100>;
590 interrupts = <29>;
591 #thermal-sensor-cells = <0>;
592 };
覆盖(这是从制造商的覆盖中抄袭而来的,用于修改后的 4.4 内核,包含一些设备的树外补丁)
76 /* Enable the touchscreen */
77 fragment@4 {
78 target = <&rtp>;
79 __overlay__ {
80 touchscreen-inverted-x;
81 touchscreen-inverted-y;
82 allwinner,ts-attached;
83 };
84 };
问题是sun4i-gpadc当我需要的是sun4i-ts。前者是通用 ADC 驱动程序,后者是我需要的触摸屏驱动程序。
root@pocketslack:/etc# udevadm info -a /sys/devices/platform/soc\@1c00000/1c25000.rtp
looking at device '/devices/platform/soc@1c00000/1c25000.rtp':
KERNEL=="1c25000.rtp"
SUBSYSTEM=="platform"
DRIVER=="sun4i-gpadc"
ATTR{driver_override}=="(null)"
如果我使用 modprobe 删除 sun4i_gpadc 和 sun4i_ts,然后使用它首先从 sun4i-ts 开始加载它们,它就会抓取设备并且正常工作。
root@pocketslack:/etc# modprobe -r sun4i_gpadc
root@pocketslack:/etc# modprobe -r sun4i_ts
root@pocketslack:/etc# modprobe sun4i_ts
root@pocketslack:/etc# modprobe sun4i_gpadc
root@pocketslack:/etc# udevadm info -a /sys/devices/platform/soc\@1c00000/1c25000.rtp
looking at device '/devices/platform/soc@1c00000/1c25000.rtp':
KERNEL=="1c25000.rtp"
SUBSYSTEM=="platform"
DRIVER=="sun4i-ts"
ATTR{driver_override}=="(null)"
我有一个 udev 规则,也是从公司的旧 repo 中获得的,我认为它可以处理这个问题,但设备仍然被 gpadc 驱动程序占用。
root@pocketslack:/etc# cat /etc/udev/rules.d/10-sun4i-ts.rules
ACTION=="add", SUBSYSTEM=="input", DRIVERS=="sun4i-ts", SYMLINK+="input/sun4i-ts-%k"
我承认自己对 udev 完全陌生,所以我不确定该规则到底告诉它做什么。我的直觉是它只是告诉它加载该模块以及如何命名它所连接的任何设备。我也不确定我是否需要 sun4i-gpadc 驱动程序,但我从内核文档中了解到,SoC 的热传感器似乎需要它才能运行。该设备还具有暴露给项目的引脚,所以我认为如果有人真的想以这种方式使用随附的 ADC,它可能也很有用。当有多个驱动程序适用时,似乎应该有一些机制来指定正确的驱动程序,我想我应该学习如何做到这一点,而不是不构建或将 gpadc 模块列入黑名单。
答案1
似乎在这个特定情况下,我确实想禁用sun4i_gpadc模块。我注意到ATTRS{driver_override}上面输出的部分udevadm info
我之前没有注意到,于是在谷歌上搜索了一下,这让我发现了更多关于设备树条目如何通过“兼容”属性确定模块的信息。这让我发现modinfo
这两个模块都在寻找相同的兼容字符串,再次查看内核配置后,我发现驱动程序不兼容,因此在这种情况下我真的不应该构建或将 gpadc 驱动程序列入黑名单,因为它依赖于!触摸屏_SUN4I。
Symbol: MFD_SUN4I_GPADC [=m] │
│ Type : tristate │
│ Prompt: Allwinner sunxi platforms' GPADC MFD driver │
│ Location: │
│ -> Device Drivers │
│ (2) -> Multifunction device drivers │
│ Defined at drivers/mfd/Kconfig:54 │
│ Depends on: HAS_IOMEM [=y] && (ARCH_SUNXI [=y] || COMPILE_TEST [=n]) && !TOUCHSCREEN_SUN4I [=m] │
│ Selects: MFD_CORE [=y] && REGMAP_MMIO [=y] && REGMAP_IRQ [=y]
抱歉,没有正确阅读原文:)