如何加载设备树覆盖

如何加载设备树覆盖

我知道这是一个主题,还有其他几个帖子。然而没有吗?他们中的一些人有一个被接受的答案,甚至是一个有用的评论。但简而言之,如何加载设备树模块(无需重新编译内核)?

到目前为止我可以找到以下方法:

  1. 在运行时加载,每个cat enI2C4.dtbo>/sys/kernel/config/device-tree/overlays.
  2. .dtbo通过在/boot/bootenv.txt和/或中指定文件在引导过程中加载/boot/uEnv.txt。在这两种情况下,内容都是(enI2C4.dtbo存储在 下/boot):
overlays=enI2C4.dtbo

可悲的是,他们都没有为我工作:

  1. device-tree目录不存在并且 mkdir 返回Operation not permitted。这个问题的大多数解决方案似乎都编译了自己的内核,我认为这并不是真正必要的,也不是我想做的事情。
  2. 编辑/创建这两个文件中的任何一个似乎没有任何效果。我既找不到我的叠加层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(这不是上游功能,但在某些内核中可用)。

相关内容