通常,如果您原样照抄Digi的开发套件或称单板机的开发底板,只做些适量的裁减,并没有硬件的大改动或调整,您是无需订制bsp来匹配自己的底板。DEY的编译选项中,支持的平台包括ccimx6sbc,ccimx6ulsbc,ccimx6ulstarter这几个开发板。如果您的底板功能和I/O变化不大,您也可以直接在现有的这几个平台做些修改,但更一般的做法是,当你根据开发底板做一些裁减和功能变换,添加或修改了默认的一些接口和功能时,这也意味着您需要添加一个新的机器平台到DEY中。这个过程包括:

  • 为U-Boot添加新的平台支持
  • 添加新的设备树文件到Linux内核中
  • 添加新的机器设备层到DEY的layer中

为u-boot添加新的机器平台支持

通常地,您可以直接使用Digi核心板自带的u-boot。我们建议您采用和Digi的开发板一样的控制芯片(比如以太网和USB的PHY等),避免对u-boot进行开发。使用Digi原生自带的UBoot,您仍可以通过uboot的脚本来实现对板子进行一些定制行为。如果您确实需要进行一些代码级的定制开发,请参考下面内容。

u-boot开发定制参考

u-boot开发定制参考

您可以从github上访问Digi核心模块的Uboot,或是在DEY的项目的session下,用bitbake -c devshell virtual/bootloader这个命令,调出核心板虚拟机的shell来查看相关代码。

平台的BSP代码

在board/digi所在的BSP目录下一般有两三个目录,其中包括了核心模块通用的BSP代码,像DDR,eMMC或NAND,PMIC,以太网等,核心模块这部分通常不用作改动。其它是单板机的目录,内有开发底板对应的BSP代码,像以太网的PHY,电源控制等。通常地,你只需要修改开发底板相应的BSP代码来匹配您的硬件,这些包括

  • 以太网的PHY,如果你用了和SBC不一样的PHY芯片
  • PMIC电压,如是使用了不同的LDO电压
  • GPIO,IOMUX等

平台的头文件

头文件位于include/configs/,从目录下的文件名可以看出它,它包括核心模块的通用配置和Digi嵌入式产品的通用配置以及单板机上的配置。通常地,您也只需要更改单板机上的配置来匹配您自己的底板硬件。

为u-boot添加一个新机器平台支持

不同平台的BSP文件有所不同,但目录位置是一样的。

点击查看cc6的bsp架构

点击查看cc6的bsp架构

board/digi目录下有:

  • ccimx6: 内有cc6核心模块所需的通用bsp代码(DDR3,eMMC,PMIC,以太网等
  • ccimx6sbc:内有cc6 SBC底板的相磁BSP代码(以太网phy,电源控制等)

注意:USDHC2控制器(开发板上的uSD卡)和USDHC4(核心模块内eMMC)一起初始化,代码在ccimx6内,尽管这是SBC上的BSP。

平台的头文件位于include/configs/,包括: ccimx6sbc.h:它定义了一些变量像:底板名称,哪个uart作为console口,以太网phy的地址和一些默认环境变量等。 ccimx6_common.h:内有一些核心模块的共同配置,像Uboot和它环境变量在eMMC中的位置,支持的接口的命令等。 digi_common.h:包含了Digi嵌入式产品的一些共同配置。 大多数自定义底板的配置,都可以在ccimx6sbc.h这个头文件中更改。

当你理解了u-boot平台代码的架构后,你就可以通过复制Digi的参考平台来定制自己的平台。有两种方法修改定制,一种是用bitbake -c devshell virtual/bootloader来调出虚拟机,在虚拟机内部去修改并重新编译,通常快速测试可以用这种方法。

点击查看示例

点击查看示例

……略

这个方法优点是,只要你有bitbake生成过镜像,就能很快调出devshell来改动,但它有个缺点是,它是在bitbake编译目录下,如果做一次clean或是升级后再次编译,就有可能丢失改动,所以说它是是一个临时的,快速验证改动的方法。

另一方式就是用git的方法直接进行版本管理和控制。您可以将自己的改动放置在github上,如果希望代码保密,也可以使用Eccee git或是自建本地的git库。

  1. git clone一个uboot到本地
  2. make <platform>_defconfig来生成make的配置文件,然后就可以直接make出uboot的镜像。
  3. 修改代码,重复上述开发过程
  4. 你也可以托管到github或私有的Eccee git仓库
  5. 如果需要整合到DEY中一起编译,可以修改DEY u-boot的recipe来指向你fork的分支,或是解压分支生成的patch到并添加到自定义的Yocto layer。参考在DEY的layer中添加自定义机器。

点击查看一个u-boot开发并托管到版本库的完整过程

点击查看一个u-boot开发并托管到版本库的完整过程

  • 您先要安装SDK,如果您之前没有安装过的话,uboot需要用SDK来交叉编译。到官方ftp去下载任一个版本。
  • 从github上下载uboot源码
 
  make -p ~/dey-workspace/uboot/cc6        在dey-workspace下创建uboot子目录和平台子目录,比如cc6或cc6ul或是你的板子名称等,并进入到该目录 
  cd ~/dey-workspace/uboot/cc6
  git clone https://github.com/digi-embedded/u-boot.git
  
  • 登录到gitlab.eccee.com,并创建一个新的私有项目,比如my-uboot
  • 先做一次初始同步
git remote rename origin old-origin
git remote add origin http://gitlab.eccee.com:11022/digirobin/my-uboot.git
可以先用git config --list查看一下当前的user.name和user.email是否你在Eccee git上的注册用户,如果不是,请用改过来。
git push -u origin --all
git push -u origin --tags
  • 修改代码,编译,验证,不断提交,每次提交请添加好注释,更多git的操作技巧请参考git常用操作
  • 正常的编译流程
make <platform>_defconfig     这里platform可以到configs目录下查找,一般是ccimx6sbc,ccimx6ulsbc,ccimx6ulstarter等
make


注:您可以利用核心板上的OTP单元来设置board_version和board_id,通常一个底板在流片完后,它的用途也基本确定下来,可以通过一个uboot脚本来一次性永久写入OTP。当写好后,uboot启动时,会自动根据OTP来设置uboot参数中的board_version和board_id,并把它的信息显示在启动信息内。其它uboot脚本可以根据这两个参数执行不同的动作,比如定义内核启动时加载不同的设备树驱动。启用程序也可以利用它执行不同的功能。
如果您不去设置OTP,您也可以通过uboot命令直接设置这两个环境参数,达到一样的效果,不过当uboot参数初始化或是损坏时,它也就变成未设置的状态,此时你就无法根据启动信息判断板子的用途。

Linux内核对特定硬件的支持是通过设备树文件实现的。设备树文件是描述硬件平台的文本文件,它是Linux内核源码树的一部分,但被单独编译成二进制文件。u-boot在启动过程会加载设备树到内存,并传递给内核。内核根据设备树中的硬件描述加载对应的设备驱动从而实现对特定硬件的支持。 CC6的设备树文件详细位置和参考:https://www.digi.com/resources/documentation/digidocs/90001546/reference/bsp/r_device_tree_files.htm

为您的底板创建设备树文件 你可以复制现有的设备树文件来加以修改定制,也可以从头创建一个设备树文件。

  • 复制cc6 SBC的设备树

1. 从dey项目中fork linux源码 2. 复制设备树文件到本地 3.定制你的平台设备树,包括确保defconfig和设备树文件匹配你的需求 4.可修改dey的linux recipe来指向您的分支,或解压生成的patch到本地并添加到你的自定义layer