基于Rockchip平台OpenHarmony动态DTS实现
(文章已获得诚迈科技资深研发工程师-潘第杰授权)
概念
在Linux中,动态更换DTB,通常指的是在运行时通过加载或替换DTB文件来改变设备树的行为或配置。设备树是描述硬件设备及其连接方式的数据结构,在嵌入式系统中特别常见,它允许系统在不修改内核的情况下动态配置硬件和设备驱动。
在运行时可以加载新的或替换现有的DTB文件,从而改变设备树的配置。这种能力使得系统能够根据需要动态调整硬件配置,而无需重新编译内核或重启系统。典型的操作包括加载不同的硬件配置文件、添加或移除设备节点、调整设备参数等。
场景描述
假设一个硬件平台在V1版本时使用了A器件,而在V2版本中,该器件被更新为B设备。如果平台软件团队只维护一套Linux代码库,通过使用设备树覆盖,可以根据硬件版本动态选择合适的.dtb文件,从而使同一套代码同时满足V1和V2硬件版本的需求,极大地增加了项目的灵活性和可维护性。
总之,设备树覆盖为Linux内核提供了一种高效、灵活的设备管理机制,特别适用于需要动态调整硬件配置或支持多个硬件版本的场景
方案描述
启动方式
Rockchip采用uboot+extlinux方式启动引导内核,其中extlinux是syslinux的一种,用于辅助启动内核,通过extlinux.conf文件来决定启动选项和参数,文件格式参考:
- default rockchip-kernel-5.10
- prompt 0
- timeout 50
- label rockchip-v1
- kernel /extlinux/Image
- fdt /extlinux/rockchip-v1.dtb
- append earlycon=uart8250,mmio32,0xfe660000 root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4
- label rockchip-v2
- kernel /extlinux/Image
- fdt /extlinux/rockchip-v2.dtb
- append earlycon=uart8250,mmio32,0xfe660000 root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4
- label rockchip-kernel-5.10
- kernel /extlinux/Image
- fdt /extlinux/toybrick.dtb
- append earlycon=uart8250,mmio32,0xfe660000 root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4
复制代码- SEARCH_STRING="rockchip"
- DTB_FILES=$(find ${dtb_path} -name "*.dtb" | grep "$SEARCH_STRING")
- echo "default rockchip-kernel-5.10" > ${EXTLINUX_CONF}
- echo "prompt 0" >> ${EXTLINUX_CONF}
- echo "timeout 50" >> ${EXTLINUX_CONF}
- echo >> ${EXTLINUX_CONF}
- for dtb_file in $DTB_FILES; do
- echo "$dtb_file"
- dtb_base=$(basename "$dtb_file" .dtb)
- echo "${dtb_base}"
- echo "label ${dtb_base}" >> ${EXTLINUX_CONF}
- echo " kernel /extlinux/${image}" >> ${EXTLINUX_CONF}
- echo " fdt /extlinux/${dtb_base}.dtb" >> ${EXTLINUX_CONF}
- cmdline="append earlycon=uart8250,mmio32,${uart} root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4"
- echo " ${cmdline}" >> ${EXTLINUX_CONF}
- echo >> ${EXTLINUX_CONF}
- done
- echo "label rockchip-kernel-5.10" >> ${EXTLINUX_CONF}
- echo " kernel /extlinux/${image}" >> ${EXTLINUX_CONF}
- echo " fdt /extlinux/${TOYBRICK_DTB}" >> ${EXTLINUX_CONF}
- cmdline="append earlycon=uart8250,mmio32,${uart} root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4"
- echo " ${cmdline}" >> ${EXTLINUX_CONF}
- echo >> ${EXTLINUX_CONF}
复制代码- static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
- {
- ...
- label_override = env_get("pxe_label_override");
- if (!m)
- return NULL;
- list_for_each(pos, &cfg->labels) {
- label = list_entry(pos, struct pxe_label, list);
- sprintf(label->num, "%d", i++);
- if (menu_item_add(m, label->num, label) != 1) {
- menu_destroy(m);
- return NULL;
- }
- if (cfg->default_label &&
- (strcmp(label->name, cfg->default_label) == 0))
- default_num = label->num;
- if (label_override && !strcmp(label->name, label_override))
- override_num = label->num;
- }
- ...
- }
复制代码