IoT 正向开发:iMX6 开发板 选型

最近需要使用一个通信模组的SDK,其运行在嵌入式linux上,包括了设备树和内核的patch、驱动、用户态库和可执行程序等,文档中说明其适配了i.MX6QSABRESD(ARM32)。我知道市面上有非常多的iMX6的开发板,作为练习IoT正向开发的开始,我希望自己编译uboot、linux运行在板子上,然后探索其中的道理。同时也是为了在使用SDK的过程中,能更好的排错。我先后体验了四家公司的开发板,分别是:百问网、迅为、飞思卡尔、野火。本以为很容易,没想到的是,倘若是怀着探索实现原理心态去看一些的开发板教程,那真是如此的令人费解。所以本篇的选型,说的不是性能,而是在我踩坑的过程中,看到了谁家的开发板能让学习者对计算机看的更透,更清楚。

尝试

百问网

首先尝试是韦东山老师百问网的IMX6ULLMINI:

相关资料:100ASK_IMX6ULL_MINI开发板

  • 9-12v供电
  • micro usb 串口

image

用这块板子的原因一是不明白,二是手里有:

  1. 开始尝试这个,大家就能看出来我这个空子纯外行,人家SDK适配的是i.MX6Q,而这块板子是i.MX6ULL
  2. 这块板子是因为鸿蒙买的:华为鸿蒙系统移植到imx6ull成功

虽然早就听闻过韦东山老师的大名,但还是第一次看他板子的相关资料,总体感觉并不是很好,但可以理解:

文档链接:https://pan.baidu.com/s/1OMX-3tFW2PUsRWdjjgCRzw 密码:oh4z

  1. 由于主要面向真的是纯新手,所以资料傻瓜化,很多步骤被封成了一个脚本,理解麻烦
  2. 由于嵌入式不同板子间的知识是有重叠的,所以产生了学习资料复用,看起来非常的乱套
  3. 由于经过多年的发展和积累,资料的维护和更新也比较乱套,导致资料非常多,但可能用不上

对于这张板子,测试直接编译uboot主线代码并烧录进SD卡是成功的,过程如下:

  git clone https://github.com/u-boot/u-boot.git
  sudo apt install -y gcc bison flex gcc-arm-linux-gnueabi libssl-dev
  cd u-boot/
  make mx6ull_14x14_evk_defconfig
  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

这里直接使用了ubuntu的apt安装的交叉编译工具,最终编译出的u-boot-dtb.imx即是uboot镜像。编译过程中需要解释的是:为什么要写mx6ull_14x14_evk_defconfig?还有没有别的?写别的行不行?

  • 首先可以在文档的204页看到编译他们提供的uboot是此参数
  • 此参数是在configs文件夹下的配置文件,如下,不同参数对应不同开发板,所以一般来说不能写别的
  ls -al ./configs/ | grep imx6ull
-rw-r--r--     1 xuanxuan  staff   2200 12 30 18:23 colibri-imx6ull-emmc_defconfig
-rw-r--r--     1 xuanxuan  staff   2710 12 30 18:23 colibri-imx6ull_defconfig
-rw-r--r--     1 xuanxuan  staff   1316 12 30 18:23 o4-imx6ull-nano_defconfig
-rw-r--r--     1 xuanxuan  staff   1744 12 30 18:23 seeed_npi_imx6ull_defconfig
  ls -al ./configs/ | grep mx6ull 
-rw-r--r--     1 xuanxuan  staff   2200 12 30 18:23 colibri-imx6ull-emmc_defconfig
-rw-r--r--     1 xuanxuan  staff   2710 12 30 18:23 colibri-imx6ull_defconfig
-rw-r--r--     1 xuanxuan  staff   1361 12 30 18:23 mx6ull_14x14_evk_defconfig
-rw-r--r--     1 xuanxuan  staff   1333 12 30 18:23 mx6ull_14x14_evk_plugin_defconfig
-rw-r--r--     1 xuanxuan  staff   1316 12 30 18:23 o4-imx6ull-nano_defconfig
-rw-r--r--     1 xuanxuan  staff   1744 12 30 18:23 seeed_npi_imx6ull_defconfig

不用理会那些封装好的图形工具,直接用dd将u-boot-dtb.imx烧录到SD卡中,然后同步一下,确保写入到SD卡中:

  sudo dd if=u-boot-dtb.imx of=/dev/sdb seek=2
  sync

其中跳过两个扇区(0x400)是imx6的镜像标准:IMX_LINUX_USERS_GUIDE.pdf

image

最后将拨码开关从1-4分别设置为ON ON ON OFF,重新上电即可从SD卡启动,通过串口可见,成功启动到uboot shell:

U-Boot 2022.01-rc4-00030-gb3f84a939f (Dec 30 2021 - 02:26:02 -0800)

CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 43C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   Could not get PHY for FEC1: addr 1
Could not get PHY for FEC1: addr 1
Get shared mii bus on ethernet@2188000
Could not get PHY for FEC1: addr 2
Get shared mii bus on ethernet@2188000
Could not get PHY for FEC1: addr 2
No ethernet found.

Hit any key to stop autoboot:  0 
=> 
=> 
=> 

之后也尝试了在这张板子上直接编译linux主线内核与buildroot文件系统,虽然有一些要改uboot启动参数的坑,但最后均成功启动。不过后来看到了其SDK适配的i.MX6Q,并且还在设备树上做了修改,我就知道用这张板子是不太可能直接跑通的,因为imx6q和imx6ull根本就是两个不同的SoC:

所以这张板子也就暂时玩到这了,其他参考:

迅为

因为之前买过迅为的4412开发板,于是搜到了他们家的确有i.MX6Q开发板:

但这只能看出来是i.MX6Q,是不是i.MX6QSABRESD呢?于是搜到:

其中提到:yocto执行配置是MACHINE=imx6qsabresd。暂时不必去理会yocto是个啥,但看到配置和目标的确一致,那看起来很靠谱了,所以淘宝买了,版本是迅为四核商业级2G+16G:

文档链接:https://pan.baidu.com/s/1JCSz_J05aujdSJOfEKNf3w 密码:wxrd

  • 12v供电
  • 9针串口,需要转USB

image

更多的资料就不放了,买完进群会给百度网盘链接,资料类似百问网的,一堆魔改的代码和纯新手教学。同样是看uboot主线代码,本以为跟百问网的一样简单,但编译时却并没看到imx6qsabresd的配置文件:

➜  ls -al ./configs/ | grep imx6qs
➜  ls -al ./configs/ | grep mx6qs 
-rw-r--r--     1 xuanxuan  staff   2224 12 30 18:23 mx6qsabrelite_defconfig

后来想到可能是飞思卡尔这张板子的配置并没有进入到uboot主线,于是找到:uboot-imx,可以通过网页上的tree标签来看到代码文件,但直接查看还是没有此配置,但如果查看lf_v2021.04此分支则能看到:

然后就是尝试用这个版本的uboot,git clone需要比较好的网速:

  sudo apt install -y gcc bison flex gcc-arm-linux-gnueabi libssl-dev
  git clone -b lf_v2021.04 https://source.codeaurora.org/external/imx/uboot-imx
  cd uboot-imx
  make mx6qsabresd_defconfig
  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
  sudo dd if=u-boot-dtb.imx of=/dev/sdb seek=2
  sync

拨码开关为1和7是ON,其余都是OFF,然后发现无法启动到uboot shell:

U-Boot 2021.04-dirty (Jan 01 2022 - 04:48:21 -0800)

CPU:   i.MX6Q rev1.3 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 29C
Reset cause: POR
Model: i.MX6 Quad SABRE Smart Device Board
DRAM:  1 GiB
PMIC: PFUZE100! DEV_ID=0xfffffffb REV_ID=0xfffffffb
write error to device: 4df782f0 register: 0x21!
write error to device: 4df782f0 register: 0x24!
write error to device: 4df782f0 register: 0x2f!
write error to device: 4df782f0 register: 0x32!
Not supported, id=11
initcall sequence 4efe3f28 failed at call 17804e89 (err=-22)
### ERROR ### Please RESET the board ###

根据PFUZE100信息排错,然后找到如下文章:

配合迅为给出的可启动的uboot源码,分析启动不了的原因主要是:

  1. PMIC(电源管理IC)与飞思卡尔官方板子不同
  2. 内存由官方板的1G升为2G

由此可见底层代码,设备树信息等不仅仅与SoC相关,还与开发板相关。通过这些移植文章也能看出来,底层适配这玩意还是需要点技术含量的,还要看懂板子上的电路是怎么与SoC接上的,反正我目前是看不太懂。

飞思卡尔

最后还是用官方的板子,google搜索imx6qsabresd,结果就是 RD-IMX6Q-SABRE 这张板子。因为没有淘宝京东,正经的渠道就是找中国的代理商购买,这很慢。因为比较着急,所以从咸鱼买了两块回来,每块2000元左右:

相关资料:SABRESDB_IMX6_QSG.pdfIMX_LINUX_USERS_GUIDE.pdf 更多资料可在产品页面底部下载,需注册NXP账号

  • 5v供电,一定注意,国内的圆口电源很多都是12v !!!
  • micro usb 串口
  • 大号SD卡,不是micro SD(TF)卡

image

  sudo apt install -y gcc bison flex gcc-arm-linux-gnueabi libssl-dev
  git clone -b lf_v2021.04 https://source.codeaurora.org/external/imx/uboot-imx
  cd uboot-imx
  make mx6qsabresd_defconfig
  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
  sudo dd if=u-boot-dtb.imx of=/dev/sdb seek=2
  sync

拨码开关为2和7是ON,其余都是OFF。官方电源是5v5a,国内一般没有这种规格的电源,淘宝可以买到思科的电源是这规格的,不过起uboot用5v2a的电源也启动成功,接电后别忘了打开SW3开关:

U-Boot 2021.04-dirty (Jan 01 2022 - 04:48:21 -0800)

CPU:   i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Automotive temperature grade (-40C to 125C) at 25C
Reset cause: POR
Model: i.MX6 Quad SABRE Smart Device Board
DRAM:  1 GiB
PMIC: PFUZE100! DEV_ID=0x10 REV_ID=0x11
MMC:   FSL_SDHC: 1, FSL_SDHC: 2, FSL_SDHC: 3
Loading Environment from MMC... *** Warning - bad CRC, using default environment

No panel detected: default to Hannstar-XGA
Display: Hannstar-XGA (1024x768)
In:    serial
Out:   serial
Err:   serial
SEC0:  RNG instantiated
switch to partitions #0, OK
mmc2 is current device
flash target is MMC:2
Net:   eth0: ethernet@2188000 [PRIME]
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot:  0 
=> 
=> 

还是官方最顺溜…

野火

其实后来使用飞思卡尔官方开发板已经把SDK成功运行了,但在前几天的SCTF遇到了用野火imx6板子出的题目:

虽然题目本身非常脑洞与无厘头,但这题让我发现野火的教程是非常用心的,正巧回公司岳哥说他那有这板子:

资料链接:i.MX Linux开发实战指南

  • 5v供电
  • 排针式TTL串口,需转USB,可直接串口供电

image

开发板上用来选择启动方式的拨码开关一直是一个比较麻烦的问题,一般来说都需要找开发手册才能知道怎么玩,但野火非常贴心的将其选择方式印到了开关附近,着实很贴心。后来发现百问网的也有,就是在板子背面,但迅为和飞思卡尔是真没有。

➜  git clone https://github.com/u-boot/u-boot.git
➜  cd u-boot/
➜  make mx6ull_14x14_evk_defconfig
➜  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

然后按照板子上的开关表格,设置为SD卡启动即可:

U-Boot 2022.01-rc4-00030-gb3f84a939f (Dec 30 2021 - 02:26:02 -0800)

CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 45C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   
Error: ethernet@20b4000 address not set.

Error: ethernet@20b4000 address not set.

Error: ethernet@20b4000 address not set.
FEC: can't find phy-handle

Error: ethernet@20b4000 address not set.
Could not get PHY for FEC0: addr 2

Error: ethernet@20b4000 address not set.
FEC: can't find phy-handle

Error: ethernet@20b4000 address not set.
Could not get PHY for FEC0: addr 2
No ethernet found.

Hit any key to stop autoboot:  0 
=> 
=> 
=> 

虽然有一些报错,但可见uboot shell还是成功启动,具体怎么适配这张板子,野火也说了:

可见野火的资料是真的告诉你,他都干了啥,你应该怎么干。

总结

对这几家板子的大体感受如下:

  • 百问网、迅为:面向纯新手,原理封装狠,较难理解
  • 野火:也面向纯新手,但是更讲原理,用心,良心
  • 飞思卡尔:权威,官方,缺点是难购买,另外要看英语资料

另外这么折腾一趟下来,也更明白底层咋回事了:

  • 上层系统屏蔽硬件差异主要有两套方案:UEFI和DTS(设备树)
  • 设备树为嵌入式系统的事实常用方案
  • 硬件信息不仅仅是SoC本身,也包括开发板的设计信息
  • 没见过直接从SoC上甩几根线出来就当开发板的原因是,SoC的目标是通用,而不是专用,使用其多少接口可以自由裁量
  • 所以SoC设计了引脚复用,例如需要几个USB接出来,这个选择的自由度由开发板电路和适配代码(设备树、驱动等)决定
  • 这些接口电路,就是板子上除了一个SoC还需要密密麻麻的电阻、电容、电感等零碎的主要原因
  • 所以综上,不同板子的切换,不是换个make参数那么简单,要有人来适配这个参数,这个过程一般就叫移植

对国内外技术差异的感受:

  • 国内国外硬件常用标准有所不同,如电源、SD卡等
  • 国内的许多板子是用国外的SoC,并无核心竞争力,势单力薄,BSP维护难,不会进入到uboot主线
  • 中文互联网对于底层相关的资料很少,可能明白这玩意的人都在公司里做板子呢…

另外最近和一些人讨论了IoT固件模拟,经过最近的正向开发,我认为IoT固件的全量模拟是没什么太大意义的:

  • 首先现在的IoT技术足够碎片,不过就是一个小计算机,只要制造者能让他跑起来,怎么玩都行
  • 其次现在的IoT技术足够复杂,可能是很多个模组,很多处理器共同搭起来的一个系统
  • 最后对于安全研究员来说,人家的东西是黑盒的,人家在各种软硬件的地方稍稍来一个花活你就会陷入困惑

但如果只针对一个特定目标,或者一种特定实现,那只要目标价值足够大,还是很有意义的。