ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

i.MX8M Plus开发板实战:从Yocto编译到镜像烧录完整指南

i.MX8M Plus开发板实战:从Yocto编译到镜像烧录完整指南 i.MX8M Plus这芯片这几年在嵌入式圈子里存在感非常高——四核Cortex-A53、一颗Cortex-M7、外加2.3 TOPS的NPU让一块开发板同时能干视觉、AI、工业控制和常规Linux应用。我第一次拿到i.MX8M Plus开发板时原以为和玩树莓派没啥区别结果发现连“把镜像跑起来”这件事都得自己从源码编译开始解先编bootloader再编内核和设备树最后还要用正确的烧录方式把镜像塞进eMMC或者SD卡。这篇文章就以i.MX8M Plus开发板的完整开发流程为线索把源码编译、烧录、镜像运行这三个环节里我亲身验证过的命令、参数和避坑点全部写清楚给正在评估这块板子、或者刚拿到板子却不知道从哪下手的同学一条可以直接照着走的路。1. 项目概述与整体开发链路设计1.1 i.MX8M Plus能做什么为什么需要全流程梳理简单说i.MX8M Plus是NXP在工业级和边缘AI领域非常能打的一颗SoC。它拥有四个Cortex-A53应用核和一个Cortex-M7实时核A53主频最高能到1.8GHzM7可以独立跑FreeRTOS这类实时系统。最关键是板载了2.3 TOPS算力的NPU配合ISP和双摄像头输入很多设备直接用一颗芯片就能完成“采集画面 本地推理 结果上报”的完整闭环。所以它常见于工业视觉检测、AI网关、医疗设备、HMI人机界面、机器人控制板这类场景。但问题也出在这颗芯片的“高配”上它不像树莓派那样有官方维护的傻瓜式桌面系统想用上完整功能通常得从源码级别构建BSPBoard Support Package。这也是很多新手第一次接触它时最头疼的地方——树莓派烧个镜像几分钟就能开机而i.MX8M Plus刚上手就面临Yocto编译、u-boot配置、设备树修改、烧录分区等一系列概念。如果没有人把全流程串一遍很容易卡在某一个环节好几天。所以我写这篇内容的核心目的就是把“拿到一块全新板卡到操作系统稳定跑起来”这个过程拆成可执行的步骤。对刚入行的同学来说这是一条可以照抄的路径对有经验但第一次接触i.MX8M Plus的工程师来说这里面的很多坑和细节也能帮你省掉反复翻文档的时间。1.2 镜像获取路径官方Yocto、预编译镜像、第三方系统怎么选很多人在最开始会纠结一个问题我是直接找现成镜像烧进去还是老老实实自己编译这里我给出一个实操结论第一步先用官方预编译镜像跑通硬件第二步再自己编译这个顺序最省时间。官方Yocto BSP源码编译适合需要定制内核、修改设备树、裁剪系统、评估量产方案的场景。难度最高但灵活性也最大。本文主要讲这条路径。NXP官方预编译镜像官网对应产品页的“Software”标签下可以下载包括bootloader、SD卡镜像、根文件系统等。适合第一次上电验证硬件、快速评估性能不适合直接拿去量产。第三方商业系统或社区发行版比如某些工业Linux厂商提供的镜像通常会带长期维护承诺对商用项目友好或者一些基于Debian/Ubuntu的社区移植版本仅供参考和把玩。我的建议是先把官方预编译镜像烧到SD卡里确认板子能正常启动到登录界面然后回头再搭Yocto环境编译自己的镜像。这样如果后面编译出来的镜像启动失败你能快速判断问题是出在硬件、bootloader还是根文件系统上。1.3 开发环境准备硬件配置、系统依赖、目录规划编译i.MX8M Plus的Yocto BSP对主机有一定要求不用顶配但太弱了会非常煎熬。先说结论建议Ubuntu 20.04或22.04 x86_64系统内存至少16GB磁盘空闲空间需要200GB以上。这不是我夸大Yocto编译过程中会下载大量源码包、编译工具链、中间产物而且最终生成的镜像加上工作目录占用空间非常可观。如果磁盘不够大概率会编到一半报错然后你还要花时间清理非常烦。首次在主机上需要安装的依赖我整理成一条命令可以直接执行sudo apt install gawk wget git-core diffstat unzip texinfo gcc-multilib \ build-essential chrpath socat cpio python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping python3-git python3-jinja2 \ libegl1-mesa libsdl1.2-dev pylint3 xterm repo这里有个细节值得注意如果想编译32位版本的某些库还需要开启dpkg的multiarch并添加i386架构但i.MX8M Plus都是64位Linux用户空间默认用不到所以装上面这些就够了不用额外折腾。对于目录规划我习惯单独建一个专用的工作目录比如~/imx8mp把repo源码、Yocto构建目录、SSTATE缓存目录和DL下载目录全部规划好。这样不会和日常文件混在一起也方便以后重新构建时复用缓存。后面所有操作我都默认在这个工作目录里进行。2. 源码编译全流程从拉取BSP到生成可烧录镜像2.1 先扫个盲Yocto的Poky、meta层、bitbake到底在干什么很多第一次接触Yocto的人会被它的概念绕晕我先用大白话解释一遍。如果把一个完整的Linux系统想象成一栋房子那Yocto就像是给你提供的一套“造房子流水线工具”而不是某个现成的房子。Poky是整套流水线的核心参考实现它规定了怎么下载材料、按什么顺序施工、最终产出什么。bitbake是流水线上具体执行任务的工人它读取一种叫配方recipe的文件告诉你每一步该干什么。meta层则是一堆配方的集合比如meta-imx就是NXP为i.MX系列芯片写的“专属施工图纸”。放到i.MX8M Plus上我们需要的东西大致包括u-boot引导加载程序、Linux内核、设备树描述板子硬件连接关系的文件、根文件系统用户能看到的/etc、/usr、/bin等。Yocto会把它们全部组织在一个构建流程里最终生成一个可以直接烧录的镜像文件。这个全自动流水线的好处是只要配置正确整套系统可以反复复现对量产和版本管理非常友好。我最早接触Yocto时也犯过一个错误总想绕过它手动交叉编译内核、手动做根文件系统。后来发现手动方案搞一两次还行一旦要定制多个软件包、维护多个版本效率会低到让人崩溃。Yocto前期学习成本确实高但一旦跑通后面的收益非常大。2.2 基于repo拉取i.MX8M Plus的BSP源码NXP的BSP源码由多个git仓库组成如果逐个git clone会非常痛苦所以官方用repo工具来统一管理。我的操作步骤如下mkdir -p ~/imx8mp cd ~/imx8mp repo init -u https://github.com/nxp-imx/imx-manifest.git -b imx-linux-kirkstone -m imx-6.1.55-2.2.0.xml repo sync -j8这里有个关键点版本号要选对。imx-linux-kirkstone是Yocto的分支名称对应的是Yocto项目的Kirkstone版本imx-6.1.55-2.2.0.xml则是BSP的具体版本描述文件表示Linux内核版本是6.1.55。如果你的项目没有特殊兼容性要求直接用最新稳定版就行。选版本时可以去NXP的imx-manifest仓库页面看release tag不要随手选一个很老的版本否则后面有可能踩到早已修复的内核bug。repo sync完成后你会看到sources目录下有几十个git仓库。不要被数量吓到绝大多数只是Yocto的通用层。和i.MX8M Plus强相关的主要是sources/meta-imx和sources/meta-nxp。前者是NXP官方对i.MX平台的一系列适配层后者是BSP新框架下的核心支持层。2.3 配置构建环境并开始编译源码同步完成后进入构建环境的关键一步cd ~/imx8mp EULA1 source setup-environment -b build-imx8mpevk这是我建议的“标准动作”。setup-environment脚本会引导你选择目标机器MACHINEi.MX8M Plus对应的机器名一般是imx8mpevk。如果你不想交互式选择也可以在命令行中直接指定MACHINEimx8mpevk EULA1 source setup-environment -b build-imx8mpevk关于DISTRO发行版配置这个脚本默认会帮你设置好通常带Wayland/Weston图形协议支持适合大多数HMI和多媒体应用场景。如果你确实是想做极致精简的framebuffer方案可以在local.conf里改但我不建议新手第一轮就折腾这个——先跑通默认配置再考虑裁剪。接下来就是正式编译bitbake imx-image-coreimx-image-core是NXP提供的一个基础镜像包含了核心系统、常用工具和多媒体组件体积比完整镜像小很多编译时间也更短。如果你需要完整的桌面体验和更多开发工具可以编imx-image-full但首次编译时间会明显拉长。我自己第一轮跑的是imx-image-core因为它的产出已经足够做大部分开发和功能验证。首次编译时间受网络和主机性能影响很大。网络好的情况下8核16GB内存的机器大概需要两到四小时网络差或者机器配置低可能要跑一晚上。编译过程中不需要你干预可以去做点别的事但偶尔要瞄一眼终端因为偶尔会有下载失败或需要确认EULA之类的情况。2.4 编译产物解读哪个文件烧到哪里编译结束后所有产物都集中在tmp/deploy/images/imx8mpevk/目录下。很多新手看到一堆文件会懵我把几个关键文件的功能列成表格文件/目录说明imx-boot-imx8mpevk-sd.bin完整的bootloader镜像包含u-boot和DDR初始化固件烧写到SD卡或eMMC的boot分区imx-image-core-imx8mpevk.wic一个完整的SD卡镜像。它内部已经分好区包含bootloader、内核、设备树和根文件系统Image编译好的Linux内核镜像文件imx8mp-evk.dtb设备树文件描述EVK评估板上的硬件连接关系u-boot.bin原始u-boot二进制一般配合DDR固件一起用*.tar.gz / *.sdcard根文件系统的压缩包或SD卡直写格式最容易犯迷糊的是imx-boot-imx8mpevk-sd.bin和.wic的关系。简单说.wic是一个“整卡镜像”里面什么都有直接用dd写进SD卡就能启动而imx-boot-imx8mpevk-sd.bin只是bootloader部分如果你需要单独更新bootloader或者用UUU往eMMC里刷写才会单独用到它。2.5 编译提速与磁盘瘦身技巧如果你要反复编译、调内核配置下面这几个技巧能帮你省下大量时间。第一合理利用SSTATE缓存。Yocto有增量编译机制第一次编译完成后各种中间产物会缓存在SSTATE目录下次重新编译相同版本时会直接复用不再重复编译。默认配置下这个目录在build-imx8mpevk/sstate-cache建议在local.conf里显式指定方便后续清理和备份。第二设置下载目录。Yocto会把下载的源码包缓存在downloads目录这样可以避免因为断网导致重新下载。在local.conf里加一行DL_DIR /home/你的用户名/imx8mp/downloads第三合理设置并行任务数。在local.conf里可以这样调BB_NUMBER_THREADS 8 PARALLEL_MAKE -j 8这两个值建议不超过主机CPU线程数给系统留出一定余量。调太高容易导致内存吃紧反而编译更慢。第四磁盘不够时可以开启rm_work它会在编译完成后自动删除临时工作目录能省下大量空间INHERIT rm_work不过要注意开了rm_work之后某些调试场景下你想进临时目录看中间编译产物就找不到了。所以我建议开发调优阶段不开确认版本稳定、只频繁迭代根文件系统时再开。3. 烧录与镜像运行实录从空板到Linux登录3.1 烧录方式选型SD卡、eMMC、NFS网络启动怎么搭针对i.MX8M Plus开发板日常使用频率最高的烧录/启动方式有四种方式适用场景优点缺点SD卡烧录学习调试、首次验证硬件操作简单直接dd写卡即可读写速度一般不适合产品量产eMMC烧录UUU产品量产、性能验证跑系统更快量产可重复操作需要板子进入USB下载模式流程稍微复杂NFS网络启动内核/驱动开发频繁修改阶段不用反复烧写省时间需要先有可用的Linux环境和网络服务TFTP网络启动只调试u-boot和内核启动参数灵活需要自己搭TFTP服务器不适合新手我第一次接触这块板子时直接用SD卡起步因为dd写卡方式“所见即所得”出问题容易排查。后面确认系统稳定了才切到eMMC做性能测试。如果你做的是量产项目建议重点研究eMMC UUU方案因为它是可自动化执行的。3.2 SD卡烧录最稳妥的起步方式拿到一个编译好的.wic镜像烧录到SD卡的操作非常简单sudo dd ifimx-image-core-imx8mpevk.wic of/dev/sdb bs1M convfsync statusprogress sync这里需要特别提醒of/dev/sdb是写整个SD卡设备不是/dev/sdb1或/dev/sdb2分区。因为.wic镜像本身已经包含分区表只要写进整个设备引导记录和多个分区都会自动就位。写之前务必用lsblk确认一下设备名避免把主机系统盘给覆盖了这个错误一旦发生后果非常严重。烧录完成后把SD卡插入开发板的卡槽。i.MX8M Plus EVK开发板上一般有一组或者两组拨码开关用来设置启动模式。SD卡启动和eMMC启动对应的拨码组合不同具体要看原理图或者开发板印刷丝印。这里我给一个实操建议拿到板子后先翻硬件手册把“eMMC启动”和“SD启动”的拨码组合截图或者拍下来再动手切。我第一次就是没记录下来切到SD启动之后忘了原来的eMMC组合折腾了好半天才在手册里翻回来。3.3 eMMC烧录使用UUU工具写镜像SD卡方案适合起步但如果你想验证eMMC的读写性能或者准备量产就必须掌握UUU工具。UUU是NXP的mfgtools工具升级版它借助u-boot的SDP协议通过USB把镜像写入板子。先安装UUU工具在Ubuntu主机上sudo apt install libusb-1.0-0-dev git clone https://github.com/nxp-imx/mfgtools.git cd mfgtools make也可以在NXP的mfgtools GitHub仓库的Release页面下载预编译好的二进制版本然后把uuu放到/usr/local/bin下。我比较推荐预编译版省事。接着要把开发板进入USB下载模式。不同板卡进入方式略有差异最常见的是按住板上的“USB烧录/恢复”按钮不放然后上电串口会看到u-boot进入uuc模式同时电脑端lsusb能看到NXP相关的USB设备。之后执行烧录命令sudo uuu -b emmc_all imx-boot-imx8mpevk-sd.bin imx-image-core-imx8mpevk.wic这个命令会把bootloader写入eMMC的boot分区把根文件系统写入用户数据分区。烧录完成后把拨码开关切回eMMC启动模式重新上电系统就会从eMMC启动。这里要注意一点UUU烧录比SD卡烧录多了“驱动识别”和“USB枚举”的环节有时候板子没进模式或者USB线是纯充电线会导致一直识别不到设备。建议用质量好的数据线尽量连主机背板的USB口少用前置USB HUB。3.4 串口启动验证从u-boot到Linux登录系统能不能跑起来不能只看板子上有没有灯亮最可靠的方式是看串口日志。i.MX8M Plus开发板通常会引出调试串口EVK板上是一排四针或者一个USB转串口接口。波特率默认是1152008N1接上USB转TTL线后在主机上打开串口终端sudo minicom -D /dev/ttyUSB0 -b 115200如果你更习惯screen也可以用sudo screen /dev/ttyUSB0 115200上电后串口里会依次出现u-boot启动信息、内核解压日志、根文件系统挂载日志。如果一切正常最后会进入登录提示符默认账号一般是root无密码或者空密码。进入到root shell后建议先把基础信息确认一遍cat /proc/cpuinfo free -h df -h ls /dev/mmcblk*cpuinfo里能看到四个Cortex-A53核心free里能看到内存容量df里能看到根文件系统挂载在哪个分区。这几个命令跑完基本可以确认板子的核心硬件和烧录的镜像都正常。然后可以测试网络接口ifconfig eth0 ping -c 3 192.168.1.1网络通不通直接影响后续开发和文件传输。如果eth0不亮先查网线、查PHY驱动是否加载不要急着改代码。如果一切顺利到这里你已经完成了从源码编译到镜像运行的全过程剩下的就是在这个基础上继续做驱动开发和业务开发了。4. 常见问题与排查技巧实录4.1 编译阶段网络、磁盘、资源不足的翻车现场Yocto编译过程中的报错看起来千奇百怪但归纳起来就几类。第一类是网络下载失败。Yocto构建时会从外部拉取大量开源包如果你的网络环境不太稳定很容易出现fetch阶段失败。此时最省事的办法是直接重跑bitbake命令它能断点续传已经下载完成的包不会重新下载。如果某个包反复失败可以在local.conf里配置BB_NO_NETWORK 0确认网络是通的或者换一个DNS/网络源。第二类是磁盘空间不足。报错信息里通常会直接提示No space left on device但很多新手会忽略前面的“磁盘”字眼反而去怀疑编译锅。排查方法很简单df -h看/目录使用率。如果超过90%先清理build-imx8mpevk/tmp下的临时文件或者把DL_DIR/SSTATE_DIR挪到大分区。第三类是编译进程被系统杀掉。长时间高负载编译时如果主机内存不够用系统会触发OOM Killer把bitbake的进程终止。症状是终端里显示Killed没有任何真正的编译错误日志。解决办法是降低BB_NUMBER_THREADS和PARALLEL_MAKE的数值或者换更大内存的机器。如果你用虚拟机编译记得给虚拟机分配足够内存否则这个坑会反复踩。4.2 烧录阶段开发板不识别、拨码错误、VFS挂载失败烧录阶段最常见的坑是把MCU的烧录思维带过来。很多之前玩STM32、用JLink或者Keil烧固件的同学第一次接触i.MX8M Plus完全不适应——没有“下载算法”没有“一键烧录按钮”bootloader和根文件系统是分开处理的。如果有这种思维惯性建议先放空记住i.MX8M Plus是跑完整Linux的SoC烧录就是“给整块存储介质分区并写入多个镜像”不是简单地把一个hex文件丢进去。UUU烧录时如果一直识别不到设备先执行dmesg | tail看USB枚举日志再确认板子是否真的进入了下载模式。有时候按住烧录按钮的时间不对或者没按到位板子还是会正常启动而不会进入SDP模式。另外某些USB线只供电不传数据这是最容易忽视的原因。启动时如果串口打印报Kernel panic - not syncing: VFS: Unable to mount root fs说明内核起来了但找不到根文件系统。这时候检查两件事一是镜像是否完整烧录到了正确分区二是uboot的启动参数里root分区的设备名和设备树是否匹配。如果在eMMC启动模式下烧录的是SD卡镜像就可能出现这类问题。4.3 启动运行阶段串口乱码、M7核不跑、外设不通串口乱码这个问题在嵌入式Linux开发板上比很多人想象的更常见。老一点的i.MX6ULL开发板上有用户遇到过终端中文乱码而i.MX8M Plus上最常见的情况是波特率设置错误。串口终端里如果出现一堆“烫烫烫”或者乱码符号第一件事不是换线而是确认波特率。i.MX8M Plus调试串口默认是115200如果minicom或screen设置成了9600、57600日志必然乱。还要确认终端编码一般推荐UTF-8。另一个容易忽略的问题是M7实时核。i.MX8M Plus的M7核默认是不运行任何代码的需要你单独编译Cortex-M7的固件并把它烧录到指定位置或者通过远程加载方式启动。如果你买板子的目标就是跑M7上的裸机或FreeRTOS程序那么先不要急着在A53 Linux里折腾把NXP官方M7 demo交叉编译好确认M7能起来再玩异构通信排查起来会轻松很多。外设不通的问题最常见原因是设备树配置不对。举例来说I2C总线上挂的传感器地址不对或者SPI片选引脚被复用成GPIO了都会导致驱动加载失败。排查时用dmesg | grep i2c或者dmesg | grep pinctrl能比较快定位。这个阶段不要盲目改内核代码先确认设备树里硬件描述是否和板卡原理图一致多数“外设没反应”的问题都出在描述错误而不是驱动代码本身。4.4 给新人的几条实战建议最后分享几个我亲身验证过的经验不一定在官方文档里能直接看到。第一拿到板子后第一轮一定先用官方预编译镜像跑通硬件再开始自己编译。这样能把“硬件问题”和“软件构建问题”分开否则机器启动不了你根本分不清是编译器配置错了还是板子本身有故障。第二遇到问题先看日志不要乱猜。嵌入式Linux的调试本质上就是看u-boot日志、内核日志、应用日志日志不会撒谎。养成用dmesg、journalctl -xe、串口日志排查问题的习惯比到处搜帖子有用得多。第三保存好每个验证过可用的组合。我在项目里会专门建一个文档记录某套BSP版本、某个设备树修改、某个内核配置后的启动结果。因为Yocto的版本组合很多今天调通的东西过两个月再改可能又忘了。记录下来能让你在维护和升级时少走很多弯路。第四从i.MX8M Plus这类异构SoC出发后续可以扩展的方向很多在A53上跑Linux做业务和网络在M7上跑FreeRTOS做硬实时控制再加上NPU跑深度学习模型这就是一个完整的边缘AI节点。先把这篇文章里的“编译、烧录、启动”全流程走通后面这些能力才有落地的基础。
返回列表