LV06-11-设备树插件-02-设备树插件的使用
怎么在linux系统中使用设备树插件?若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.2的64位版本 | |
VMware® Workstation 17 Pro | 17.6.0 build-24238078 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 | |
linux内核 | linux-4.19.71(NXP官方提供) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
nxp-imx/linux-imx/releases/tag/v4.19.71 | NXP linux内核仓库tags中的v4.19.71 | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 | NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) | |
Source Code | https://elixir.bootlin.com/linux/latest/source | linux kernel源码 |
kernel/git/stable/linux.git - Linux kernel stable tree | linux kernel源码(官网,tag 4.19.71) | |
https://elixir.bootlin.com/u-boot/latest/source | uboot源码 |
一、移植设备树插件
1. 挂载 configfs 虚拟文件系统
1.1 内核配置
configfs 虚拟文件系统是什么?这个我们后面会学习,现在主要是学习设备树插件的使用。首先我们打开 Linux 内核源码, 输入以下命令打开 menuconfig 配置界面。
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean |

界面打开之后,按以下菜单找到对应的配置
1 | File systems ---> |

将这一项从 M
改为*
。修改完进行保存。
1.2 编译验证
将编译之后的内核镜像烧写到开发板上, 接着可以使用 mount 命令检查 configfs 虚拟文件系统是否挂载成功:
1 | mount |

没有configfs相关的内容就说明没有自动挂载上,我们可以用mount命令手动挂载:
1 | mount -t configfs none /sys/kernel/config |
挂载成功如下图:

2. 配置内核支持设备树插件
我们打开 Linux 内核源码, 还是输入以下命令打开 menuconfig 配置界面。
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean |
2.1 Device Tree overlay
界面打开之后,按以下菜单找到对应的配置项
1 | Device Drivers ---> |

2.2 Overlay filesystem support
按以下菜单找到对应的配置项
1 | File systems ---> |

3. 移植驱动
如果已经学完了 configfs 虚拟文件系统的数据结构。其实完全可以自己编写驱动实现一个设备树插件。 但是我们没有必要重复造轮子, github 上有大神编写好的设备树插件驱动,例如 GitHub - ikwzm/dtbocfg: Device Tree Blob Overlay Configuration File System:

这就是一个驱动模块的源码,我们修改Makefile配置好源码的路径和编译工具,直接编译就可以了,编译完毕会得到一个ko文件,这个后面会用到。
4. 总结
移植设备树插件主要包括以下几个步骤 :
(1)配置内核支持挂载 configfs 虚拟文件系统。
(2)配置内核支持设备树插件。
(3)移植设备树插件驱动。
其中(1)和(2)完成后要注意重新编译内核,再把开发板中的内核更新一下。
二、设备树插件实例
1. 设备树插件中添加节点
1.1 设备树插件
1.1.1 设备树源码
我们用 imx6ull-alpha-emmc.dts 中led灯的这个设备节点:
1 | /dts-v1/; |
我们写一个设备树插件 imx6ull-alpha-emmc-overlay.dts 如下:
1 | /dts-v1/; |
我们把主设备树中的 sdev_led 节点移动到设备树插件中去。需要注意的是,这样在设备树插件中添加节点的操作似乎并不会自动取生成platform_device,所以如果用的平台设备驱动的话可能会有问题。
1.1.2 编译设备树插件
我们使用以下命令进行编译设备树插件:
1 | ./dtc -I dts -O dtb imx6ull-alpha-emmc-overlay.dts -o imx6ull-alpha-emmc-overlay.dtbo |
设备树的编译可以看demo中的makefile,它包含了一些其他的设备树和头文件,所以编译会复杂一点。
1.2 更新内核和设备树
我们按照前面的更新内核和设备树,然后重启设备。然后将imx6ull-alpha-emmc-overlay.dtbo和dtbocfg.ko 放到开发板中。
1.3 环境准备
1.3.1 configfs文件系统挂载
在内核根文件系统中,有一个文件 /proc/filesystems ,它表示当前内核支持的文件系统,通常是编入内核的文件系统类型,但也可以通过模块加入新的类型。可以通过命令 cat /proc/filesystems 检查 configfs 是否支持。 支持的话就会有如下信息 :

不支持的话可以看前面的笔记对内核进行配置。支持之后,我们可以用mount命令看一下有没有挂载上,若是没挂载的话,后面加载驱动是不会生成对应的目录的。可以使用以下命令挂载:
1 | mount -t configfs none /sys/kernel/config |
1.3.2 加载dtbocfg.ko
我们通过以下命令加载:
1 | insmod dtbocfg.ko |
会有如下打印信息:

加载成功应该会生成 /sys/kernel/config/device-tree/overlays 目录:

要是没有的话,就注意用mount看一下是不是成功挂载了configfs。
1.4 设备树插件测试
- (1)查看未添加设备树插件的时候的设备树情况
1 | ls /proc/device-tree/ |

- (2)我们进入 /sys/kernel/config/device-tree/overlays 目录
1 | cd /sys/kernel/config/device-tree/overlays |
- (3)新建一个dtbo_demo目录
1 | mkdir dtbo_demo |
然后进入这个目录就会发现这个目录下自动生成了两个文件:dtbo和status。
- (4)将设备树插件的内容写入到dtbo中
1 | cd /sys/kernel/config/device-tree/overlays/dtbo_demo |
- (5)使能 dtbo
1 | cd /sys/kernel/config/device-tree/overlays/dtbo_demo |
- (6)查看设备树插件加载的节点
1 | ls /proc/device-tree/overlay_node/ |

- (7)删除使用 dtbo 修改的节点
1 | cd /sys/kernel/config/device-tree/overlays |
然后我们再查看一下 /proc/device-tree,就会发现没有 overlay_node 节点了:

2. 修改后设备树节点属性
2.1 设备树插件
我们用 imx6ull-alpha-emmc.dts 中led灯的这个设备节点:
1 | /dts-v1/; |
我们写一个设备树插件 imx6ull-alpha-emmc-overlay.dts 如下:
1 | /dts-v1/; |
我们把主设备树中的 sdev_led 节点移动到设备树插件中去。需要注意的是,这样在设备树插件中添加节点的操作似乎并不会自动取生成platform_device,所以如果用的平台设备驱动的话可能会有问题。
2.2 开发板测试
- (1)加载设备树插件之前节点的情况

- (2)加载设备树插件之前加载驱动

看到会报一个状态读取失败,然后我们运行测试demo,发现可以正常操作,这个应该是因为我内部判断了,但是没有返回错误的原因,不过这里不影响测试。测完卸载驱动。
- (3)加载设备树插件
1 | 挂载configfs文件系统 |

可以看到这里生成了一个 overlay_node 目录,里面包含了name和status属性。
- 重新加载设备的驱动
1 | insmod sdriver_demo.ko |

发现还是报错的,这是因为status属性并不是在/alpha/sdev_led/status
,而是alpha/sdev_led/overlay_node/status
所以获取的时候出现了问题,这个大概了解就可以了,后续使用设备树插件的话需要注意这个事情。