前言:

i.MX8M Plus 开发板是一款拥有 4 个 Cortex-A53 核心,运行频率 1.8GHz;1 个 Cortex-M7 核心,运行频率 800MHz;此外还集成了一个 2.3 TOPS 的 NPU,大大加速机器学习推理。

全文所使用的开发平台均为与NXP官方合作的FS-IMX8MPCA开发板(华清远见imx8mp开发板),支持Weston、ubuntu20.04、Android11 等操作系统;同时支持 Xenomai 硬实时内核、EtherCAT 总线、TSN 时间敏感网络、ROS1.0、ROS2.0 等工业与机器人领域应用;可以用于工业互联网、人工智能、边缘计算、多屏异显等应用方向。华清远见研发中心编写了大量开发教程并录制了丰富视频教学资源免费提供给大家!

开发板更多资料领取可关注华清远见在线实验室领取~~~

源码编译、烧录、镜像运行

本章节将介绍如何对 I.MX8M Plus 开发 Linux 系统编译与烧录。

Yocto 系统源码编译

 本小节主要讲述如何编译 imx8mp 的源码,涉及 Yocto 源码和 Android 源码两部分。

建立源码目录

⚫ Yocto 源码导入

首先我们在 ubuntu“家”中建立 imx8mp 文件夹,用于存放 imx8mp 源码

linux@ubuntu:$ cd ~

linux@ubuntu:$ mkdir imx8mp 

下面将【华清远见-I.MX8M Plus 开发资料\程序源码\imx-yocto-bsp】该目录下的 imx-yoctobsp.tar.xz.xx 文件全部导入虚拟机中刚创建好的 imx8mp 目录下。使用如下命令解压缩

linux@ubuntu:$ cat imx-yocto-bsp.tar.xz* | tar Jxvf -

解压缩完成后会得到 imx-yocto-bsp 目录,该目录有如下文件。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux

该目录下的 bsp_source 目录中主要存放了,系统源码包括 tf-a、u-boot、kernel 等,后面

的 linux 系统开发部分会重点讲述。sources 文件夹下主要存放 Yocto 构建系统相关的配置文件。

由于 imx-yocto-bsp 在编译过程中会依赖很多外部源码包,我们可以在编译过程中通过编

译程序自行下载,也可以使用我们提供好的完整依赖包。

因为依赖包较大,因此将此部分单独制作成了依赖包镜像【华清远见-I.MX8M Plus 依赖

包】将该 ISO 文件中所有的 downloads.tar.xz*文件导入到 imx-yocto-bsp 源码目录下,并解压。

linux@ubuntu:$ cd ~/imx8mp/imx-yocto-bsp

linux@ubuntu:$ cat downloads.tar.xz* | tar Jxvf

解压完成后会在 imx-yocto-bsp 目录下得到 downloads 目录。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_02

downloads 文件不是必须的,如果您不编译 yocto 源码只做 linux 系统开发可以不用解压

此目录。

Weston 编译

Yocto 的编译环境需要在 ubuntu18.04 linux 发行版进行编译,并且编译前请确保 ubuntu 中以安装本文档前面提到的《Yocto 开发环境搭建》开发工具。

1) 将当前工作目录切换到 imx-yocto-bsp 文件夹下

linux@ubuntu:$ cd ${HOME}/workdir/imx8mp/imx-yocto-bsp

2) 导入编译配置

linux@ubuntu:$ DISTRO=fsl-imx-xwayland MACHINE=imx8mp-ai-robot source imx-setup-release.sh -b build-imx8mp-ai-robot-xwayland

3) 如果是第一次配置,需要同意一些协议

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_03

之后按空格到协议最后

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_04

输入 y 会如下如下界面

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_05

4) 编译源码

编译 multimedia 镜像

linux@ubuntu:$ bitbake imx-image-multimedia

编译人工智能镜像

linux@ubuntu:$ bitbake imx-image-full

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_06

注意:在编译 Yocto 系统时确保 ubuntu 主机可以连接互联网由于 fsl-imx-xwayland 涉及到的源码较多,因此编译会比较耗时。

编译完成后所生成的镜像文件保存在 tmp/deploy/images/imx8mp-ai-robot/目录下。

⚫ multimedia 镜像说明

imx-boot-imx8mp-ai-robot-sd.bin-flash_ai_robot

imx-image-multimedia-imx8mp-ai-robot.wic.bz2

⚫ 人工智能镜像说明

imx-boot-imx8mp-ai-robot-sd.bin-flash_ai_robot

imx-image-full-imx8mp-ai-robot.wic.bz2

此外 Yocto 还支持一些在不同层上可用的图像。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_07

烧录

在烧录镜像之前我们需要先按照下图连接必要的数据线:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_08


基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_09

按照上图分别连接 USB 数据线、电源线、以及调试串口(由下向上分别为 5V、M4_TX、

M4_RX、A53_TX、A53_RX、GND)。这里我们只连接 GND、A53_RX、A53_TX 三条线。

在上电之前我们还需要按住开发板上的红色烧录按钮,让开发板进入烧录模式。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_10

imx8m plus Weston 支持 emmc 启动。在进行烧录之前要确保 uuu 工具可以正常连接开发板。

将前面《weston 编译》小节编译生成的“multimedia 镜像”或者“人工智能镜像”导出到Windows 主机中进行烧录,如果没有编译 weston 可以使用我们【华清远见-I.MX8M Plus 开发资料\系统镜像\imx8mp-ai-car-weston】目录下的 imx-image-multimedia-imx8mp-ai-robot.wic.bz2镜像文件和 imx-boot-imx8mp-ai-robot-sd.bin-flash_ai_robot 文件进行烧录。

该文件中包含启动镜像,rootfs 等镜像,我们可以通过不同的命令来烧写相关的镜像文件。

在进行烧录之前需要先打开 cmd 窗口,并且将工作命令切换到该目录下进行烧录。

⚫ eMMC 烧录

当使用 uuu 工具烧录镜像时,可以使用如下命令进行 Weston 镜像烧写。

dos@windows:$uuu-bemmc_all .\imx-boot-imx8mp-ai-robot-sd.bin-flash_ai_robot .\imximage-multimedia-imx8mp-ai-robot.wic.bz2

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_11

烧录成功如下图

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_12

烧录完成后使开发板完全断电重启即可。

Yocto 系统功能演示

weston 功能演示

硬件连接

在开发板上电之前需将调试串口、网线接入网口 1。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_13

在上电之前我们需要先按照下图连接必要的数据线:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_14

按照上图连接调试串口(由下向上分别为 5V、M4_TX、M4_RX、A53_TX、A53_RX、GND)。

这里我们只连接 GND、A53_RX、A53_TX 三条线。

设置调试串口

在烧写过程中可以通过调试串口来监控烧写过程,串口调试可以借助 XSHELL 来进行相

关调试,XSHELL 已经在前面章节安装完成,这里只需要配置一下相关串口即可。

双击桌面上的“XSHELL 6”图标打开。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_15

开启 xshell 后在自动弹出的对话框中单击“新建”按钮。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_16

在“新建会话属性”中“协议(P)”中选择“SERIAL”,名称可以自定义。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_17

下面需要对串口进行配置。首先需要确定串口在系统中的 COM 口是哪个端口。可以在

设备管理器中查找。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_18

可以看到这里的串口为“COM3”

下面点击 xshell 界面中左侧的“串口”按钮。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_19

选择端口号为“COM3”(需要根据当前实际环境选择),波特率为:115200,数据位:

8,停止位:1,奇偶校验:无,流控制:无。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_20

配置好之后点击“确定”按钮。将看到如下界面。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_21

先选中刚刚新建的 COM 选项后点击“连接”

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_22

看到如上界面则说明打开成功。

显示屏幕选择

开发板默认启动 HDMI 如果需要启动 LCD 屏幕需按照下列方法设置。

⚫ MIPI-DSI

对应实际接口如下图:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_23

MIPI-DSI 屏幕与主板连接需要以下部件: MIPI-DSI 屏幕 1 个、信号转换板 1 个、30 pin

FPC 软排线 1 条、2x20 MIPI-DSI 双绞线一条

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_24

MIPI-DSI 模组与主板 MIPI-DSI 接口连接如下:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_25

连接完成后如果需要默认启动 MIPI 屏幕,我们需要调整默认设备树,在 u-boot 中将 fdt_

file 变量修改为 imx8mp-ai-robot-mipi070.dtb 启动系统即可。

u-boot=> setenv fdt_file imx8mp-ai-robot-mipi070.dtb

u-boot=> save

Saving Environment to MMC... Writing to MMC(1)... OK

⚫ LVDS

对应实际接口如下图:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_26

LVDS 屏幕与主板连接需要以下部件: LVDS 屏幕 1 个、信号转换板 1 个、30 pin FPC 软排

线 1 条、2x20 LVDS 双绞线一条

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_27

LVDS 模组与主板 LVDS 接口连接如下:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_28

连接完成后如果需要默认启动 LVDS 屏幕,我们需要调整默认设备树,在 u-boot 中将 fdt

_file 变量修改为 imx8mp-ai-robot-lvds070.dtb 启动系统即可。

u-boot=> setenv fdt_file imx8mp-ai-robot-lvds070.dtb

u-boot=> save

Saving Environment to MMC... Writing to MMC(1)... OK

⚫ MIPI-DSI+LVDS+HDMI 多屏异显

使用 MIPI-DSI+LVDS 多屏显示时,需同时连接 MIPI-DSI 和 LVDS 两个屏幕,同时需要

在 u-boot 中将 fdt_file 变量修改为 imx8mp-ai-robot-mipi-lvds-dual.dtb 启动系统即可

u-boot=> setenv fdt_file imx8mp-ai-robot-mipi-lvds-dual.dtb

u-boot=> save

Saving Environment to MMC... Writing to MMC(1)... OK 

设备树文件说明

开发板支持多种设备和不同接口的屏幕,因此在使用不同设备时需要预先设置好要启动的设

备树文件,下表是设备树对应关系

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_29

当我们需要适配不同功能的屏幕时,可按照以上描述在 uboot 中修改 fdt_file 环境变量为

相应的设备树名称即可。

屏幕旋转

可以通过在/etc/xdg/weston/weston.ini 文件中添加[output]选项修改屏幕默认方向,在

weston.ini 文件中添加如下配置可实现 90°旋转。

⚫ HDMI

[output]

name=HDMI-A-1

mode=1920x1080@60

transform=rotate-90

⚫ MIPI-DSI

[output]

name=DSI-1

mode=800x1280@60

transform=rotate-90

⚫ LVDS

[output]

name=LVDS-1

mode=800x1280@60

transform=rotate-90

多媒体

音频播放(此部分依赖 I.MX8MP UPS 电源扩展板)

root@imx8mp:# pactl list sinks

root@imx8mp:# amixer -c 2 cset name='0 Speaker Driver Playback Volume Left' '200'

root@imx8mp:# amixer -c 2 cset name='0 Speaker Driver Playback Volume Right' '200'

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_30

可以看到 Sink #2 为本地声卡,因此可以使用下面的命令进行音频测试

root@imx8mp:# gst-launch-1.0 filesrc locatinotallow=xxx.mp3 ! mpegaudioparse ! mpg123audiodec !

audioconvert ! alsasink device=plughw:2

使用上面的命令可以使用耳机播放音频文件,上面 xxx.map3 就是在本地的音频文件。

⚫ 音频录制

调整 mic 录音音量

root@imx8mp:# amixer set 'CH4' 100%

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_31

查看 mic 的设备编号

root@imx8mp:# arecord -l

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_32

这里我们选择 imx-audio-micfil 所对应的 Card。这里即为 Card 0

录制 WAV 音频文件

root@imx8mp:# arecord -Dhw:0,0 -c 8 -r 16000 -f S32_LE capture5.wav

这里-Dhw:0,0 中的 0,0 即为 Card 0,Subdevice #0 所对应的设备,音频录制完成后使用“Ctrl+C”可结束录音。最终会生成 capture5.wav 音频文件。

⚫ 视频播放

此部分可兼容 HDMI、MIPI-DSI、LVDS 屏幕

root@imx8mp:# gst-launch-1.0 filesrc locatinotallow=720P.mp4 ! qtdemux name=d d.video_0 !

queue ! h264parse ! vpudec ! queue ! waylandsink

⚫ 摄像头采集(此部分依赖摄像头模组)

摄像头与主板连接需要以下部件: 摄像头模组 1 个、信号转换板 1 个、15 pin FPC 软排线 1

条、2x10 MIPI-CSI 双绞线一条

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_33

摄像头模组与主板摄像头 1 接口(也可连接至摄像头 2 接口)连接如下:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_34

可以使用如下指令进行摄像头图像采集

root@imx8mp:# gst-launch-1.0 v4l2src device=/dev/video2 ! autovideosink

有线网络配置 

Weston 系统默认网卡为 DHCP 自动获取 IP 地址,如果需要固定 ip 地址可以修改

/lib/systemd/network/80-wired.network 文件指定 IP 地址。

/lib/systemd/network/80-wired.network 默认配置如下

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_35

假设现在需要将 IP 地址固定为 192.168.72.2,网关为 192.168.72.1,DNS 为 192.168.72.1,

我们修改[Match]配置如下

[Match]

Name=eth0

KernelCommandLine=!nfsroot

[Network]配置如下

[Network]

DNS=192.168.72.1

Address=192.168.72.2/24

Gateway=192.168.72.1

将原有的[DHCP]配置删除。

修改完成后配置文件如下所示

接入网线,重启系统。后查看 IP 地址如下:

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_36

 无线网络配置

进入到 Linux 系统的终端后使用 wpa_passphrase 工具连接 WiFi。这里 WiFi 模块有 M.2

接口和 USB 接口两种模块,如下图:

⚫ AP6212 模组

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_37


基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_38

⚫ CM358 模组

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_39


基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_40

⚫ USB 模组

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_41

M.2 接口可支持 AP6212 与 CM358 两种模组。USB 模组可直接使用,CM358 模组与

AP6212 模组需按照相应步骤操作。

⚫ CM358 模组

如果使用的是 imx8mp-ai-car-weston 镜像则需要执行以下命令加载 M.2 驱动,出厂默认

镜像无需执行(USB 模组可跳过驱动加载)

root@imx8mp:# modprobe moal mod_para=nxp/wifi_mod_para.conf

⚫ AP6212 模组

ap6212 模组需要调整默认设备树,在 u-boot 中将 fdt_file 变量修改为 imx8mp-ai-robotap6212.dtb 启动系统即可。(USB 模组与 CM358 模组可跳过)

u-boot=> setenv fdt_file imx8mp-ai-robot-ap6212.dtb

u-boot=> save

Saving Environment to MMC... Writing to MMC(1)... OK

由于 CM358 模组与 AP6212 模组所使用的设备树文件是两种不同的配置,下表是设备树对应关系

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_42

当我们需要适配不同功能的屏幕时,可按照以上描述在 uboot 中修改 fdt_file 环境变量为

相应的设备树名称即可。

连接 WiFi 步骤

启动 wpa_supplicant 应用(CM358 设备名称为 mlan0, USB 模组与 AP6212 模组名称为

wlan0):

root@imx8mp:# wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B

扫描周边 WiFi 热点启动扫描

root@imx8mp:# wpa_cli -i wlan0 scan

查看扫描结果:

root@imx8mp:# wpa_cli -i wlan0 scan_results

添加一个网络连接

root@imx8mp:# wpa_cli -i wlan0 add_network

配置 WiFi 热点的名称 ssid: 

root@imx8mp:# wpa_cli -i wlan0 set_network 1 ssid '"WiFi 的 SSID"'

配置 WiFi 热点的密码 psk:

root@imx8mp:# wpa_cli -i wlan0 set_network 1 psk '"WiFi 的密码"

连接第 1 个保存的连接

root@imx8mp:# wpa_cli -i wlan0 select_network 1

分配 IP 地址

无线网络设置静态 IP 地址与有线网络方法类似,只是这里对应的配置文件为

【/lib/systemd/network/】目录下的 51-wireless.network 文件。将本文件中的[Network]配置参照有线网络的配置设置即可。IP 配置完成后使用如下命令添加 DNS 服务器即可正常进行网络连接 

root@imx8mp:# echo "nameserver 114.114.114.114" > /etc/resolv.conf

root@imx8mp:# echo "nameserver 8.8.8.8" >> /etc/resolv.conf

root@imx8mp:# ping baidu.com

注意:CM358 设备名称为 mlan0, USB 模组与 AP6212 模组名称为 wlan0。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_43

开机自动连接指定 WiFi

此部分仅限 fs-aicar-qt-system-rt-sdk-kinetic-imx8mp-ai-robot 和 imx-robot-system-rt-sdkkinetic-imx8mp-ai-robot 系统,imx8mp-ai-car-weston 镜像暂不支持下列操作。

要实现开机自动连接 WiFi 我们需要先使用下面的命令设置好 SSID 和密码

注意:CM358 设备名称为 mlan0, USB 模组与 AP6212 模组名称为 wlan0。

root@imx8mp:# wpa_passphrase "WiFi 的 SSID" "WiFi 的密码" >> /etc/wpa_supplicant/

wpa_supplicant-wlan0.conf

设置完成后/etc/wpa_supplicant/wpa_supplicant-wlan0.conf 会出现 network 配置选项。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_44

如果需要重新设置 SSID 和密码,则需要先手动将红框中的内容删除,然后再次执行上面

的命令。

开启 systemd-networkd 和 wpa_supplicant 两个服务重启后生效

注意:CM358 设备名称为 mlan0, USB 模组与 AP6212 模组名称为 wlan0。

root@imx8mp:# systemctl enable systemd-networkd.service

root@imx8mp:# systemctl enable wpa_supplicant@wlan0.service

如果需要立即生效则使用下面命令重启服务

root@imx8mp:# systemctl restart systemd-networkd.service

root@imx8mp:# systemctl restart wpa_supplicant@wlan0.service

蓝牙连接(此部分只能使用 M.2 接口)

建立串口和蓝牙协议层的数据连接通道(AP6212 模组可跳过)

root@imx8mp:# hciattach /dev/ttymxc2 any 115200 flow

开启蓝牙设备

root@imx8mp:# hciconfig hci0 up

查看设备地址

root@imx8mp:# hcitool dev

扫描蓝牙设备

root@imx8mp:# hcitool scan

4G/5G 网络连接(此部分需要外接 4G、5G 模组)

系统启动后可以查看目录/dev/ttyUSB* 

root@imx8mp:# ~# ls /dev/ttyUSB*

/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3

发现设备之后执行 quectel-CM 命令进行拨号

root@imx8mp:# quectel-CM &

[02-07_15:52:57:850] WCDMA&LTE_QConnectManager_Linux&Android_V1.1.34

[02-07_15:52:57:851] ./quectel-CM profile[1] = (null)/(null)/(null)/0, pincode = (null)

[02-07_15:52:57:853] Find /sys/bus/usb/devices/2-1.6 idVendor=2c7c idProduct=0125

[02-07_15:52:57:854] Find /sys/bus/usb/devices/2-1.6:1.4/net/eth1

[02-07_15:52:57:854] Find usbnet_adapter = eth1

[02-07_15:52:57:854] Find /sys/bus/usb/devices/2-1.6:1.4/GobiQMI/qcqmi1

[02-07_15:52:57:854] Find qmichannel = /dev/qcqmi1

[02-07_15:52:57:916] Get clientWDS = 7

[02-07_15:52:57:948] Get clientDMS = 8

[02-07_15:52:57:980] Get clientNAS = 9

[02-07_15:52:58:012] Get clientUIM = 10

[02-07_15:52:58:045] Get clientWDA = 11

[02-07_15:52:58:079] requestBaseBandVersion EC20CEFILGR06A01M1G

[02-07_15:52:58:172] requestGetSIMStatus SIMStatus: SIM_READY

[02-07_15:52:58:204] requestGetProfile[1] 3gnet///0

[02-07_15:52:58:236] requestRegistrationState2 MCC: 460, MNC: 1, PS: Attached, DataCap:

LTE

[02-07_15:52:58:268] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED

[02-07_15:52:58:333] requestRegistrationState2 MCC: 460, MNC: 1, PS: Attached, DataCap:

LTE

[02-07_15:52:58:365] requestSetupDataCall WdsConnectionIPv4Handle: 0xe18031b0

[02-07_15:52:58:461] requestQueryDataCall IPv4ConnectionStatus: CONNECTED

[02-07_15:52:58:493] ifconfig eth1 up

[ 190.441795] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready

[02-07_15:52:58:506] busybox udhcpc -f -n -q -t 5 -i eth1

udhcpc: started, v1.31.1

udhcpc: sending discover

udhcpc: sending select for 10.224.108.150

udhcpc: lease of 10.224.108.150 obtained, lease time 7200

[02-07_15:52:59:060] /etc/udhcpc.d/50default: Adding DNS 123.123.123.123

[02-07_15:52:59:060] /etc/udhcpc.d/50default: Adding DNS 123.123.123.124

 

由以上 log 消息可以看到 4G 模块默认分配到的 IP 为 10.224.108.150

我们可以使用 ifconfig 命令进行查看

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_45

如果在 ifconfig 可以看到有 IP 地址为 10.224.108.150 则说明 4G 模块已联网成功。

⚫ EC200s(4G cat1)

首先启动开发板至终端,之后接入 EC200s 模块,稍等片刻终端出现如下提示

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_46

这个信息说明模块已经被正确识别,我们需要连接模块的 USB1 节点,进行 AT 指令控

制使用 microcom 连接/dev/ttyUSB1 节点

root@imx8mp:# microcom /dev/ttyUSB1

接下来我们需要进行拨号,首先需要确定模块的工作模式是不是 RNDIS 模式

root@imx8mp:# AT+QCFG="usbnet"

如果模组返回“+QCFG: "usbnet",3”则说明模块在 RNDIS 模式

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_47

如果返回的不是上图所示则需要执行如下指令切换模式

root@imx8mp:# AT+QCFG="usbnet",3

工作模式切换完成后需要设置接入点

root@imx8mp:# at+qicsgp=1,1,"uninet"

如果当前是 2g、3g 网络则需要设置 AT+QIACT=1

root@imx8mp:# AT+QIACT=1

最后使用 AT+QNETDEVCTL=1,1,1 进行拨号

root@imx8mp:# AT+QNETDEVCTL=1,1,1

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_48

设置完成后按 ctrl+x 退出 microcom。回到终端获取 ip 地址

root@imx8mp:# udhcpc -fnq -i usb1

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_49

出现该提示说明拨号成功。使用 ifconfig 查看网络状态会发现 usb1 已经被正确分配到了 IP 地址

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_50

系统编译

Yocto 的编译环境需要在 ubuntu18.04 linux 发行版进行编译,并且编译前请确保 ubuntu 中以安装本文档前面提到的《Android 系统编译环境》开发工具。

Android 源码导入

接下来导入 Android 部分源码,如果您不需要重新编译 Android 系统,此部分可以跳过。

首先我们在 ubuntu“家”中建立 imx8mp 文件夹,用于存放 imx8mp 源码。如果在此前已

经创建了 imx8mp 文件夹则不必再次执行。

linux@ubuntu:$ cd ~

linux@ubuntu:$ mkdir imx8mp

将【华清远见-I.MX8M Plus-Android11 源码包】该目录下的 android11.tar.xz.xx 文件全部

导入虚拟机中刚创建好的 imx8mp 目录下。使用如下命令解压缩

linux@ubuntu:$ cat android11.tar.xz* | tar Jxvf –

解压缩完成后会得到 android11 目录,该目录有如下文件。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_51

该目录下的 vendor/nxp-opensource 目录中主要存放了系统源码包括 tf-a、u-boot、kernel

等源码。

安装 u-boot 编译时环境

imx8m plus 在编译 u-boot 前需要先安装 gcc-arm-8.3-2019.03 交叉编译工具链,该交叉编

译器位于【华清远见-I.MX8M Plus 开发资料\工具软件】目录下的 gcc-arm-8.3-2019.03-x86_6

4-aarch64-linux-gnu.tar.xz。

将 gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz 导入到 ubuntu 系统中,通过如下

命令将其解压到/opt 目录下。

linux@ubuntu:$ sudo tar -xvf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -C /opt

解压完成后在/opt 目录下得到 gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu 文件夹

设置环境变量

现在我们以及将交叉编译工具链安装完成了,接下来需要将上面交叉编译工具链所在位

置在.bashrc 文件夹中设置一个环境变量。

linux@ubuntu:$ vi ~/.bashrc 

在文档末尾添加如下环境变量

export AARCH64_GCC_CROSS_COMPILE=/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-lin

ux-gnu/bin/aarch64-linux-gnu-

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_52

Android11 源码

首先将当前工作目录切换到 android 源码所在目录

linux@ubuntu:$ cd ${HOME}/imx8mp/android11

该目录内容如下

 

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_53

⚫ 选择默认 LCD 屏幕

Android11 系统我们支持 MIPI LCD、LVDS LCD 以及 HDMI,我们可以在编译前选择默

认支持的显示设备。

首先打开 device/nxp/imx8m/evk_8mp/BoardConfig.mk 文件,修改 TARGET_BOARD_DT

S_CONFIG 变量即可更换默认显示设备。例如将默认设备改为 lvds lcd 则将该变量改为

如下:TARGET_BOARD_DTS_CONFIG := imx8mp:imx8mp-ai-robot-lvds070.dtb

linux@ubuntu:$ vi device/nxp/imx8m/evk_8mp/BoardConfig.mk

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_54

导入编译环境变量

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板

linux@ubuntu:$ lunch evk_8mp-userdebug

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_55

执行编译脚本

linux@ubuntu:$ ./imx-make.sh -jx

这里可以使用通过-jx 参数选择多线程编译,但是由于 Android11 编译过程对内存空间要

求较大,所以不建议使用多线程编译

使用如下命令组合也能实现相同功能

linux@ubuntu:$ source build/envsetup.sh

linux@ubuntu:$ lunch evk_8mp-userdebug

linux@ubuntu:$./imx-make.sh bootloader kernel -jx

linux@ubuntu:$ make -jx

编译完成后会在“out/target/product/evk_8mp”目录下生成相关镜像文件

root/:根文件系统所在目录

system/:android 系统镜像目录,用于生成 system.img

ramdisk.img:由 root 目录生成的镜像文件

vendor.img:vendor 镜像,用于挂载 Android 下的/vendor 目录

boot.img:一个复合镜像,包括 linux 内核,ramdisk 和一些启动参数

单独编译 u-boot

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译 u-boot

linux@ubuntu:$ ./imx-make.sh bootloader -j4

编译完成后会在 out/target/product/evk_8mp/目录下生成 u-boot 文件

单独编译 kernel

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh            

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译 Linux 内核

linux@ubuntu:$ ./imx-make.sh kernel -c -j4

 编译 boot.img

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译 boot.img

linux@ubuntu:$ ./imx-make.sh bootimage -j4

或者使用如下命令也可以实现相同功能

linux@ubuntu:$ ./imx-make.sh kernel -j4

linux@ubuntu:$ make bootimage -j4

编译完成后会在 out/target/product/evk_8mp/目录下生成 boot.img 文件

编译 dtbo

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh            

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译 dtbo 设备树

linux@ubuntu:$ ./imx-make.sh dtboimage -j4

或者使用如下命令也可以实现相同功能

linux@ubuntu:$ ./imx-make.sh kernel -j4

linux@ubuntu:$ make dtboimage -j4

编译完成后会在 out/target/product/evk_8mp/目录下生成 dtbo 文件

生成 fastboot_imx_flashall 烧写脚本

注意:该部分功能目前版本暂时没有实现,在后续发布版本中会实现

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译 fastboot_imx_flashall

linux@ubuntu:$ make -j4 fastboot

编 译 完 成 后 会 在 “ out/host/linux-x86/bin ” 目 录 下 生 成 linux 环 境 下 运 行 脚 本 ,“out/host/windows-x86/bin”目录下生成 Windows 环境下运行脚本。

编译差分资源包

Android 平台提供 Google diff arithmetic 差分机制,升级包支持整包和差分包。整包即包

含整个 system 分区中的数据文件,而差分包则仅包含两个版本之间改动的部分。

利用整包升级好比对电脑进行重作系统,格式分系统分区,并将新系统数据写入分区;

而利用差分包升级不会格式化 system 分区,只是对其中部分存储段的内容进行重写。除

升级包之外,制作过程中还会涉及到另一种 zip 包,代码中称之为 target-files zipfile,我

称之为差分资源包。

 编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行           

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译差分资源包

linux@ubuntu:$ ./imx-make.sh bootloader kernel -j4

linux@ubuntu:$ make target-files-package -j4     

编译完成后会在“out/target/product/evk_8mp/obj/PACKAGING/target_files_intermediates/e

vk_8mp-ota-**.zip”目录下生成差分资源包。

编译差分包

生成差分包前需要准备两个差分资源包。一个是上一版本的差分资源包我们称为 PREVI

OUS-target_files.zip,还有一个新生成的差分资源包我们称为 NEWtarget_files.zip。

关于差分资源包的生成可以参考上一节内容

编译差分资源包

linux@ubuntu:$ out/host/linux-x86/bin/ota_from_target_files -i PREVIOUS-target_files.zip NEWtarget_files.zip incremental-ota.zip

编译完成后会在当前目录下生成差分包 incremental-ota.zip。

编译整包

导入编译环境变量,此操作只需要执行一次,如果已经执行过此操作则不需要再次执行

linux@ubuntu:$ source build/envsetup.sh

执行 lunch 命令,我们选中的是 i.MX 8M Plus 开发板,此操作只需要执行一次,如果已经

执行过此操作则不需要再次执行

linux@ubuntu:$ lunch evk_8mp-userdebug

编译差分资源包

linux@ubuntu:$ ./imx-make.sh bootloader kernel -j4

linux@ubuntu:$ make otapackage -j4

编译完成后会在“out/target/product/evk_8mp/evk_8mp-ota-**.zip”目录下生成整包。

android11 系统烧录

Android 系统的 eMMC 卡分区如下图所示:

userdata 分区用于存放应用程序、系统配置数据库等解压缩代码/数据。在正常引导模式

下,根文件系统首先从引导分区用 ramdisk 挂载,然后将逻辑系统分区挂载并切换为根。在recovery 模式下,根文件系统从引导分区用 ramdisk 挂载。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_56


基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_57

android 镜像

在烧录镜像之前我们需要先按照下图连接必要的数据线

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_58

按照上图分别连接 USB 数据线、电源线、以及调试串口(由下向上分别为 5V、M4_TX、

M4_RX、A53_TX、A53_RX、GND)。这里我们只连接 GND、A53_RX、A53_TX 三条线。

在上电之前我们还需要按住开发板上的红色烧录按钮,让开发板进入烧录模式

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_59

imx8m plusAndroid 支持 emmc 启动。在进行烧录之前要确保 uuu 工具可以正常连接开发板。

将前面《Android11 编译》小节编译生成的“Android 镜像”导出到 Windows 主机中进行

烧录,如果没有编译 Android 可以使用我们【华清远见-I.MX8M Plus 开发资料\系统镜像

\imx8mp-android11】目录下提供好的系统镜像。

首先进入到对应屏幕的目录下,可以看到有如下文件

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_60

该文件夹中包含启动镜像,rootfs 等镜像,我们可以通过不同的命令来烧写相关的镜像文

件。在进行烧录之前需要先打开 cmd 窗口,并且将工作命令切换到该目录下进行烧录。

使用如下命令可以将 Android 镜像烧录至 eMMC

dos@windows:$ .\uuu_imx_android_flash.bat -f imx8mp -a -e

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_61

该脚本默认烧写的显示设备为 HDMI,我们可以用以下指令修改默认显示设备

MIPI070 屏幕烧写指令

dos@windows:$ .\uuu_imx_android_flash.bat -f imx8mp -d mipi070 -a -e

⚫ LVDS070 屏幕烧写指令

dos@windows:$ .\uuu_imx_android_flash.bat -f imx8mp -d lvds070 -a -e

烧录成功显示结果如下

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_62

DM-verity

DM-verity 是 Android 系统安全的重要部分,它能保证 Android 的 vendor 和 system 镜

像文件中的内容是真实可靠的。所以如果打开了 DM-verity 功能那么如果我们通过 fastboot 修改 android 系统的 system 分区或者 vendor 分区,那么 DM-verity 校验时就会出错,因此在fastboot 之前需要先将 DM-verity 解锁。

DM-verity 解锁有两种办法,第一是通过 android 的开发者选项进行解锁,第二种是通过

adb 指令进行解锁。

 通过 android 开发者选项解锁 DM-verity

首先启动 android 系统依次点击“设置”->“开发者选项”->“解锁 OEM”

在开发板串口终端执行如下命令,进入 bootloader

root@imx8mp:# reboot bootloader

在开发板的 bootloader 中输入如下指令解锁 oem

u-boot=> fastboot oem unlock

等待解锁完成后即可使用 fastboot 进行烧录 了

⚫ 通过 adb 指令解锁 DM-verity

首先启动 android 系统,然后在 Windows 的 cmd 窗口下执行如下指令

dos@windows:$ adb root

dos@windows:$ adb disable-verity

dos@windows:$ adb reboot

烧录指定分区

有些时候在调试阶段可能只是改动了一部分程序,并不想每次都重新烧录镜像,这种情

况下可以通过 fastboot 工具只烧录与程序改动相关的分区,而不必每次都重新烧录。

启用了动态分区功能后 fastboot 分为两种模式,一种位 u-boot fastboot。另一种是 userspace fastboot。在不同的模式中,可以操作的分区也是不一样的,下表两种模式对应的分区。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_63

1) U-Boot fastboot 模式

首先启动开发板,进去 uboot 终端

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_64

在开发板的串口终端输入如下指令

u-boot=> fastboot 0

执行完此命令后,打开主机的“CMD”窗口,执行如下命令,可以看到有一个 fastboot 设

dos@windows:$ fastboot devices

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_65

接下来可以通过fastboot命令进行分区烧录,由上面的分区对应表可知在该模式下可以对boot,

vendor_boot, dtbo, vbmeta, misc, super 和 bootloader0, gpt, mcu_os 分区进行操作。

⚫ boot 分区

dos@windows:$ fastboot flash boot_a boot.img

⚫ vendor_boot 分区

dos@windows:$ fastboot flash vendor_boot_a vendor_boot.img 

⚫ dtbo 分区

dos@windows:$ fastboot flash dtbo_a dtbo-imx8mp.img

⚫ vbmeta 分区

dos@windows:$ fastboot flash vbmeta_a vbmeta-imx8mp.img

⚫ mcu_os 分区

dos@windows:$ fastboot flash mcu_os imx8mp_mcu_demo.img

2) userspace fastboot 模式

userspace fastboot 模式可以通过 android 系统的 adb 命令进入,也可以通过 uboot 进入。

通过 adb 命令进入,需要先进入 android 系统,然后再主机的“CMD”终端下输入如下指

令。需要注意的是在启动过程中不要进入 uboot 终端。 

dos@windows:$ adb reboot fastboot

之后系统会重启,然后进入 userspace fastboot 模式,可以在终端中使用如下命令发现 fast

boot 设备即为成功。

dos@windows:$ fastboot devices

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_66

通过 uboot 进入时需要先进入 uboot 终端。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_ubuntu_67

在开发板的串口终端输入如下指令

u-boot=> fastboot 0

执行完此命令后,打开主机的“CMD”窗口,执行如下命令进入 userspace fastboot 模式

dos@windows:$ fastboot reboot fastboot

之后系统会重启,此时“CMD”终端会短暂出现“< waiting for any device >”这个是由于

userspace fastboot 正在启动稍等即可,最后执行成功结果如下。

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_串口_68

可以在终端中使用如下命令发现 fastboot 设备即为成功。

dos@windows:$ fastboot devices

基于imx8m plus开发板全体系开发教程2:源码编译、烧录、镜像运行_linux_69

接下来可以通过 fastboot 命令进行分区烧录,由上面的分区对应表可知在该模式下可以对 system, system_ext,vendor, product 分区进行操作。

⚫ system 分区

dos@windows:$ fastboot flash system_a system.img

⚫ system_ext 分区

dos@windows:$ fastboot flash system_ext_a system_ext.img

⚫ vendor 分区

dos@windows:$ fastboot flash vendor_a vendor.img

⚫ product 分区

dos@windows:$ fastboot flash product_a product.img