如果给您一台搭载骁龙技术、运行Linux的全新设备,您愿意花时间搞清楚正确的硬件配置以便启动系统,还是愿意只需选择正确的配置即可开始使用设备?
能够交付多设备树是非常重要的。设备制造商往往会针对多个主板或SKU创建一份多功能软件包。软件包中包含多设备树的二进制表示(DTB),每个二进制表示对应不同的硬件配置,以便操作系统知道加载项。
本文探讨了我们在为主板(硬件)匹配正确DTB (软件)方面的理想方法。我们希望引入一个用于向设备树添加主板标识符的通用定义。本文的目的是激发对于Board-id的进一步讨论。Board-id机制与供应商和OEM无关,但通过它引导加载程序可以选择适当的DTB。
(本文是我在嵌入式开源峰会上的演示“交付多设备树:如何确定哪个DTB适合我的主板”的摘要。更多信息和链接,请参见下文。)
选择正确的设备树–背景
设备树(即DTB;术语可互用)是描述硬件的社区解决方案。您可以将硬件描述嵌入Linux内核,但必须包含所有硬件(传感器、显示器、协处理器等),这将会占用大量空间。因此,操作系统构建者为他们支持的硬件创建了设备树。
我们的骁龙 X Elite平台有多个SKU,每个SKU都有不同的设备树。我们希望将所有硬件描述打包至软件,以便在启动骁龙 X Elite设备时,加载正确的设备树。
但是,在选择拟使用的设备树和将其硬件描述传递给内核之间存在着脱节。通常情况下,bootloader会执行此项操作,但内核不能支配bootloader,因此,我们必须解决选择问题。
作为OEM或开发人员,您可以自行选择DTB,或者通过某种独特的下游方式选择DTB。
在现有技术条件下,最好是由您选择拟使用的设备树。这样,软件包仅包含正确的DTB,不需要bootloader作出选择。例如,在构建环节,您可以通过运行系统命令的方式包含正确的设备树。在使用引导镜像的情况下,您可以为拟包含的相应设备树提供一个参数。或者,您还可以将内核映像加入至DTB。
所有其他解决方案均为下游方式,涉及到打包多个DTB,以便bootloader进行选择。
总之,我们希望在支持多SKU和参考设计的单个软件包中交付多设备树。这样,当您(和我们)的客户收到新板时,可以减少不必要的麻烦。
我们在Qualcomm Technologies,Inc.(QTI)使用的方法
QTI如何识别不同的设备?说实话,即使过了10年,我们仍然没有解决这个问题。不过,我们也做过以下尝试。
硬件标识符寄存器
在我们的片上系统中,每个SoC都有一个硬件标识符寄存器,将其标识为骁龙 X Elite、骁龙 8 Gen 3等。
我们的参考板属于其他类型。我们所有的业务部门——汽车、物联网、扩展现实等,都有不同的参考板平台;例如,Qualcomm 机器人 RB3 Gen 2开发套件。硬盘中有一个分区包含参考板附加标识符。
而参考设备也属于其他类型。例如,对于我们的移动芯片组,我们有一个类似于电话的参考设备,有一个标识符。
将这些标识符合并,这样,一个QTI软件包可以包含大约20个DTB,具有100个以上的叠加(overlay)。
下游代码
在下游代码中,我们有一个解决方案。在设备树中,我们插入qcom,msm-id、qcom,board-id、qcom,pmic-id和qcom,oem-id等属性,描述字段如何映射到配置数据表(CDT)和SoC硬件标识符:
多年前,我们曾经设法将这种方法提交上游。但社区未予采纳,因为涉及到内核从未使用的Qualcommspecific属性。
编码至DT映像
我们有与DTB打包格式相关的元数据,因此,另一种方法是将其编码至DT映像标头,以此方式识别硬件。但是,如果元数据未嵌入文件本身,则管理元数据也是件麻烦的事情。
上游办法
以下是已成为上游方法的选项。
使用可兼容的字符串
设备树中可以支持文本字符串,此,我们尝试按照如下格式描述硬件:
compatible = "qcom,<SoC>(-<soc_version>)(-<foundry_id>)-<plat_type>(/<subtype>)(-<plat_version>)(-<mb>MB)(-<panel>-panel)(-boot-<boot>)(-<pmic>(-v<pmic_version>)){0-4}"
按照这样的格式,您可以得到如下字符串:
qcom,apq8074-v2.0-2-dragonboard/1-v0.1-512MB-panel-qHD-boot-emmc_sdc1-pm8941-v0.2-pm8909-v2.2
问题是仅用兼容字符串描述QTI硬件可能需要80个以上的字符。这种复杂性使得在主流bootloader中添加对我们硬件的支持变得非常困难,因为每个bootloader都需要自定义匹配和维护算法。尽管如此,有迹象表明,Chromebook、Tegra等供应商可能会采用此技术。
兼容字符串通常包括SoC。但是,配合一种型号的Chromebook使用的DTB可能无法与另一种型号的Chromebook相配合,即使它们均搭载相同的SoC,例如Qualcomm SM6115。因此,如果找不到匹配项,依靠兼容字符串的回退很快就会成为问题。
让bootloader决定
另一种方法是将所有节点放入DT,然后让bootloader确定启用项或禁用项。问题在于,这需要在bootloader和设备树之间创建联系。因此,如果您不使用 U-Boot或依赖于Linux的上游bootloader,那么更新设备树可能不会那么简单。如果bootloader要求设备树具有特定的节点,但您希望设备树不包含节点,或者您希望添加新的节点,则修复程序将变得无效。然后呢?
下游方法
其中大多数方法已在上文中介绍:
- 在QTI,我们使用MSM ID和主板ID。它是一位字段,在ROM中某个区域包含一些魔数。
- Google Pixel采用类似的方法,使用soc_ID字段。
- Android开源项目(AOSP)使用dtbo.img元数据。它为每个DTB添加一个可选ID、revision和u32或某些自定义字段。如上所述,如同使用DT映像一样,您可以将硬件标识符编码至DTB映像元数据。
- U-Boot使用文件名匹配DTB。它包含测试DTB是否匹配的属性,与兼容字符串类似。
- coreboot使用基于供应商、主板、主板ID和SKU ID组合的配置。 尽管这种方法还不能通用,不足以胜任各种情形,而且肯定不能在上游形成标准,但是让我们看到了一些希望。
DTB选择功能–愿望清单
首先,我们希望尽量减少新板支持工作。我们不希望添加自定义字符串解析,因为每次需要支持新的bootloader的时候都必须进行检查。最好是设计出一种读取主板属性的方法,然后匹配。
其次,我们期望硬件提供的信息(例如SoC修订版号)要远超软件的需要。
另外,我们希望此功能可以转换为不同的DTB包装格式。目前,U-Boot、Android Bootloader (ABL)和coreboot都使用不同的格式。如果这些格式能够通用,并且内核成为真实数据的来源,这将是一大进步。
最后,我们需要一个匹配这些属性的记录机制,以便任何匹配DTB都能正常工作,无论是采用U-Boot、coreboot、grub还是ABL。
下一步
如本文开头所述,本文的目的是激发对当前RFC(“为多DT选择添加主板ID支持”)的进一步讨论。我们希望社区能认真考虑,加入或提供意见。
我们知道,我们不是唯一一家因缺乏可靠解决方案而受到影响的供应商。我们也知道,集体智慧往往可以洞见我们可能忽略的事项。希望大家踊跃通过Qualcomm Developer Discord发表意见。
如需了解更多信息,请参阅我在嵌入式开源峰会2024上的相关演示(以下是幻灯片和视频的链接):
Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries ("Qualcomm"). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.
本文是原作者个人意见的表达,并非体现 Qualcomm Incorporated 或其子公司(“Qualcomm”) 的意见。本文内容仅供参考,并非 Qualcomm 作出的陈述,也不代表 Qualcomm 认可其内容。本网站还可能包括非 Qualcomm 网站和资源的链接或引用。对于本网站引用或提供的可以访问的任何非 Qualcomm 网站或第三方资源,或者上述网站或资源的链接,Qualcomm 不作任何声明、保证或其他承诺。