我知道这是一个主题,还有其他几个帖子。然而没有吗?他们中的一些人有一个被接受的答案,甚至是一个有用的评论。但简而言之,如何加载设备树模块(无需重新编译内核)?
到目前为止我可以找到以下方法:
- 在运行时加载,每个
cat enI2C4.dtbo>/sys/kernel/config/device-tree/overlays
. .dtbo
通过在/boot/bootenv.txt
和/或中指定文件在引导过程中加载/boot/uEnv.txt
。在这两种情况下,内容都是(enI2C4.dtbo
存储在 下/boot
):
overlays=enI2C4.dtbo
可悲的是,他们都没有为我工作:
- 该
device-tree
目录不存在并且 mkdir 返回Operation not permitted
。这个问题的大多数解决方案似乎都编译了自己的内核,我认为这并不是真正必要的,也不是我想做的事情。 - 编辑/创建这两个文件中的任何一个似乎没有任何效果。我既找不到我的叠加层
find /proc/device-tree/ -type f -exec head {} + | grep I2C
,也没有dmesg
返回任何特殊的东西。
那么我在这里缺少什么?是否有第三种选择,或者我在这里缺少的东西(可能是愚蠢的)?
作为背景和附加信息:
我尝试在 i.MX 8M plus 上启用 I2C4:
$ lsb_release -a
Distributor ID: ampliPHY
Description: ampliPHY GNU/Linux BSP-Yocto-NXP-i.MX8MP-PD22.1.0 (hardknott)
Release: BSP-Yocto-NXP-i.MX8MP-PD22.1.0
Codename: hardknott
该.dts
文件是:
/dts-v1/;
#include "imx8mp.dtsi"
&i2c4 {
clock-frequency = <400000>;
pinctrl-names = "default", "gpio";
status = "okay";
};
这是 bootpromp(挂载 /boot/ 后),其中/boot/bootenv.txt
和/boot/uEnv.txt
文件都已就位。
[ OK ] Mounted /boot.
[ OK ] Reached target Local File Systems.
Starting Create Volatile Files and Directories...
[ OK ] Finished Create Volatile Files and Directories.
Starting Network Name Resolution...
Starting Network Time Synchronization...
[ OK ] Started Network Name Resolution.
[ OK ] Started Network Time Synchronization.
[ OK ] Reached target Network.
[ OK ] Reached target Host and Network Name Lookups.
[ OK ] Reached target System Initialization.
[ 6.550051] imx-sdma 30bd0000.dma-controller: sdma firmware not ready!
[ 6.557338] imx-sdma 30bd0000.dma-controller: sdma firmware not ready!
[ 6.564225] imx-sdma 30bd0000.dma-controller: sdma firmware not ready!
[ 6.570968] imx-sdma 30bd0000.dma-controller: sdma firmware not ready!
[ 6.577572] imx-sdma 30bd0000.dma-controller: sdma firmware not ready!
[ 6.597437] imx-cdnhdmi sound-hdmi: snd_soc_register_card failed (-517)
[ OK ] Started 6.605376] fsl-aud2htx 30cb0000.aud2htx: Unbalanced pm_runtime_enable!
;39mDaily Cleanup of Temporary Di[ 6.613814] fsl-aud2htx 30cb0000.aud2htx: failed to init imx pcm dma: -517
rectories.
[ OK ] Reached target System Time Set.
[ OK ] Reached target System Time Synchronized.
[ OK ] Reached target Timers.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Listening on PC/SC Smart Card Daemon Activation Socket.
Starting sshd.socket.
[ OK ] Started NFS status monitor for NFSv2/3 locking..
[ OK ] Listening on sshd.socket.
[ OK ] Reached target Sockets.
[ OK ] Reached target Basic System.
Starting Save/Restore Sound Card State...
[ OK ] Started D-Bus System Message Bus.
[ OK ] Started Start fan control, if configured.
[ OK ] Started Linux Firmware Loader Daemon.
Starting User Login Management...
Starting Permit User Sessions...
[ 6.927296] imx-sdma 30bd0000.dma-controller: firmware found.
Starting OpenSS[ 6.934041] imx-sdma 30bd0000.dma-controller: loaded firmware 4.6
H Key Generation...
[ OK ] Finished Save/Restore Sound Card State.
[ OK ] Finished Permit User Sessions.
[ OK ] Finished OpenSSH Key Generation.
[ OK ] Reached target Sound Card.
[ OK ] Started Getty on tty1.
[ OK ] Started Serial Getty on ttymxc0.
[ OK ] Reached target Login Prompts.
[ OK ] Started User Login Management.
[ OK ] Reached target Multi-User System.
[ 7.198435] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[ 7.204785] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
____ _ _ __ __ _____ _____ ____
| _ \ | | | |\ \ / /|_ _|| ____| / ___|
| |_) || |_| | \ V / | | | _| | |
| __/ | _ | | | | | | |___ | |___
|_| |_| |_| |_| |_| |_____| \____|
_ __ __ ____ _ ___ ____ _ _ __ __
/ \ | \/ || _ \ | | |_ _|| _ \ | | | |\ \ / /
/ _ \ | |\/| || |_) || | | | | |_) || |_| | \ V /
/ ___ \ | | | || __/ | |___ | | | __/ | _ | | |
/_/ \_\|_| |_||_| |_____||___||_| |_| |_| |_|
答案1
正如另一个答案中所解释的,在运行时加载覆盖(无需重新启动)需要定制的 Linux 内核,即您需要修补内核源代码,调整配置,然后编译并安装您的定制 Linux 内核,除非您的 Linux 发行版已经提供了这样修改过的内核。
通常,覆盖不会在运行时应用,而是在引导加载程序中应用,通常是 u-boot。在 u-boot 中向内核设备树添加覆盖层有多种方法,最常见的一种是使用各种 u-boot 命令“手动”将设备树和所有覆盖层加载到内存中,然后使用中的每个覆盖层更新设备树转动,最后用生成的设备树启动 Linux 内核。这些步骤通常放在引导脚本(u-boot 引导时执行的脚本)中。该脚本通常称为 boot.scr,它是一种二进制映像格式,人类不可读,也无法修改。 (boot.scr可以通过编译名为boot.cmd的脚本源代码文件来生成)。
但大多数人永远不需要处理这些细节。根据您使用的 Linux 发行版,这一切都已得到处理,并且有一个引导脚本(或某种替代机制)将加载并应用 u-boot 环境变量中列出的任何覆盖,该变量可能被命名为“overlays” ,并且您可以通过编辑通常称为 /boot/uEnv.txt 的文件来修改它。
再说一遍 - 所有这些事情的工作方式都不同,具体取决于发行版架构师如何设置 u-boot、引导脚本、内核和 Linux 系统。例如,u-boot 环境也可以存储在硬件芯片中,例如 eeprom 或 spi nvram、硬盘驱动器上的特殊分区或扇区或其他一些秘密位置。由于修改 u-boot 环境变量或引导脚本可能会成为安全漏洞,因此系统通常会阻止用户这样做,即使具有 root 权限也是如此。即使您可以修改 u-boot 环境,引导脚本也可能不包含添加覆盖的功能。这取决于您的发行版提供的内容。
最后一个例子:如果你碰巧使用 Armbian 并且碰巧有一个 Armbian 支持覆盖的平台,那么你很幸运:你只需要修改存储在 /boot/armbianEnv.txt 中的变量“overlays”。该变量是一个空格分隔的覆盖列表,u-boot 在引导 Linux 内核之前将尝试添加这些覆盖。添加所需叠加层的文件名,不带 .dtbo 后缀。您在此处添加的覆盖必须存在于 /boot/dtb/XXX 下,其中 XXX 是与您的平台对应的子目录。请注意,添加不起作用的覆盖层可能会阻止您的系统启动,尽管通常 u-boot 会跳过有故障的覆盖层并显示错误消息。
甚至还有一个工具“armbian-add-overlay”,允许您从 .dts 覆盖源代码文件编译自定义覆盖 .dtbo 文件。生成的 .dtbo 会自动复制到 /boot/overlay_user/ ,并将引用添加到 /boot/armbianEnv.txt 中的 user_overlays u-boot 环境变量。整洁的!
另请参见例如https://docs.armbian.com/User-Guide_Allwinner_overlays/
答案2
因为/sys/kernel/config/device-tree/overlays/
您应该有一个构建的内核CONFIG_OF_CONFIGFS=y
(这不是上游功能,但在某些内核中可用)。