Yocto 构建基于官方 imx6ull-14x14-evk 的 ubuntu 镜像

这篇文章主要介绍 imx6ull 的 bring up:

  1. 搭建 ubuntu + docker + yocto 的开发环境
  2. Yocto 中创建自定义 layer,并集成到构建系统
  3. 基于官方 machine 配置,创建自定义 machine(如 my-imx6ull),并指定自定义的设备树(Device Tree)和 U-Boot 配置
  4. 通过 patch 或直接替换的方式,定制和集成自己的设备树源码到 Yocto 构建流程中
  5. 编译、烧录并在目标 i.MX6ULL 硬件上验证自定义镜像和设备树的生效,包括在 U-Boot 阶段检查 model 和 compatible 属性。

0. 首先进入 docker 虚拟机并初始化 yocto环境

bash 复制代码
# 进入docker
docker run -it --rm \
   --security-opt seccomp=unconfined \
  --name yocto-imx6ull \
  -v ~/yocto-build:/home/yoctouser/yocto-build \
  -v ~/.ssh:/home/yoctouser/.ssh:ro \
  -v /etc/localtime:/etc/localtime:ro \
  --dns 114.114.114.114 \
  yocto-imx6ull:22.04 /bin/bash

cd ~/yocto-build/imx-yocto
# 使用 Yocto 提供的脚本创建 layer 骨架
# initialize environment
source imx-setup-release.sh -b build

1. 创建自定义 layer

bash 复制代码
bitbake-layers create-layer ../sources/meta-myboard

这会生成 meta-myboard/ 目录结构。然后使能该 layer:

bash 复制代码
# 方式 1:手动编辑 bblayers.conf
bitbake-layers add-layer ../sources/meta-myboard

# 方式 2:或者修改 imx-setup-release.sh,让以后自动添加
# 在 imx-setup-release.sh 中找到写入 bblayers.conf 的地方,追加:
 echo "BBLAYERS += \"\${BSPDIR}/sources/meta-myboard\"" >> $BUILD_DIR/conf/bblayers.conf
# 添加好之后,重新source sh 文件
source imx-setup-release.sh -b build_my_imx6ull

2. 创建新的 Machine 配置

这是最关键的一步。创建一个新的 machine(例如 my-imx6ull),继承 imx6ull14x14evk 的所有默认配置,再针对性覆盖。

2.1. 创建 machine 文件

bash 复制代码
mkdir -p sources/meta-myboard/conf/machine

cat > sources/meta-myboard/conf/machine/my-imx6ull.conf << 'EOF'
#==============================================================================
# My Custom i.MX6ULL Board (继承并扩展 imx6ull14x14evk)
#==============================================================================

# 继承官方 EVK 的所有基础配置
require conf/machine/imx6ull14x14evk.conf

# 扩展 MACHINE_OVERRIDES,确保能匹配到 EVK 的 bbappend
MACHINEOVERRIDES =. "imx6ull14x14evk:"

# 自定义机器名称
MACHINE_NAME = "my-imx6ull"

# 指定自定义 Device Tree(见下一步)
KERNEL_DEVICETREE = "nxp/imx/my-imx6ull-emmc.dtb"

# 如果有 U-Boot defconfig 差异,可指定新的 config
#UBOOT_CONFIG = "my_imx6ull"
#UBOOT_CONFIG[my_imx6ull] = "my_imx6ull_emmc_defconfig"

UBOOT_CONFIG = ""
UBOOT_MACHINE = "my_imx6ull_emmc_defconfig"

# 机器特性(根据实际硬件增删)
MACHINE_FEATURES:remove = "wifi bluetooth"
# MACHINE_FEATURES:append = "can"

# 镜像格式(按需)
IMAGE_FSTYPES += "wic.zst"

EOF

2.2 修改 Device Tree

硬件差异 90% 体现在 Device Tree 上:引脚复用(pinctrl)、外设节点(UART/SPI/I2C/ETH)、regulator、时钟等。

创建 bsp recipe, 路径: yocto-build/imx-yocto/sources/meta-myboard/recipes-bsp/u-boot/

目录结构:

bash 复制代码
- u-boot-imx_%.bbappend
- files
  - my-imx6ull-emmc.dts(适用于方案A)
  - xxx_${comments}.patch(适用于以下方案B)

方式 A:完全替换 .dts(改动较大时)

  • 先从官方内核源码中复制一份 imx6ull-14x14-evk.dts 为 my-imx6ull-emmc.dts
  • 根据自己的硬件信息做相应修改

方式 B:在 NXP 官方dts的基础上修改 (比较小的改动,本工程的实现方式)

这种是通过 patch 的方式,把修改注入到 官方的设备树和uboot的源码。

以下是如何导出 patch,以添加 my-imx6ull-emmc.dts 为例。

  • 进入 docker, 并初始化 yocto 环境
bash 复制代码
docker run -it --rm \
   --security-opt seccomp=unconfined \
  --name yocto-imx6ull \
  -v ~/yocto-build:/home/yoctouser/yocto-build \
  -v ~/.ssh:/home/yoctouser/.ssh:ro \
  -v /etc/localtime:/etc/localtime:ro \
  --dns 114.114.114.114 \
  yocto-imx6ull:setup_git  /bin/bash

cd ~/yocto-build/imx-yocto

MACHINE=my-imx6ull DISTRO=fsl-imx-fb source ./imx-setup-release.sh -b build-myboard
  • 进入 uboot 的开发环境
bash 复制代码
devtool modify u-boot-imx
# 此时会在 /home/yoctouser/yocto-build/imx-yocto/build-myboard/workspace/sources
# 路径下出现 uboot的源码
  • 创建 my-imx6ull-emmc.dts
bash 复制代码
# 在 uboot的源码里 copy 官方设备树为 my-imx6ull-emmc.dts
cd /home/yoctouser/yocto-build/imx-yocto/build-myboard/workspace/sources/uboot
cd arch/arm/dts/
cp imx6ull-14x14-evk-emmc.dts my-imx6ull-emmc.dts
  • 修改 my-imx6ull-emmc.dts
dts 复制代码
/*
 * Copyright 2019 NXP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 */

/dts-v1/;
#include "imx6ull-14x14-evk-emmc.dts"

/ {
    model = "Para's i.MX6 ULL Board in U-Boot";
    compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull", "fsl,para-imx6ull";
};
  • 添加完 自己的设备树以后, 还要把设备树添加进对应的 makefile

修改 /arch/arm/dts/Makefile b/arch/arm/dts/Makefile:

在 dtb-$(CONFIG_MX6ULL) += 处加上新的设备树

bash 复制代码
dtb-$(CONFIG_MX6ULL) +=
    imx6ulz-bsh-smm-m2.dtb \
    imx6ulz-14x14-evk.dtb \
    imx6ulz-14x14-evk-emmc.dtb \
    my_imx6ull_emmc.dtb
  • 指定uboot 使用 my-imx6ull-emmc.dts

修改 include/configs/mx6ullevk.h

bash 复制代码
"fdt_file=undefined\0" \
"myfdt_file=my-imx6ull-emmc.dtb\0"
...
...
...
    "if test $fdt_file = undefined; then " \
        "echo WARNING: Could not determine dtb to use; " \
    "fi; " \
...
    "setenv fdt_file ${myfdt_file}; " \
  • 修改 uboot启动信息

修改文件 board/freescale/mx6ullevk/mx6ullevk.c

bash 复制代码
# 在函数 int board_late_init(void) 里
...
 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    env_set("board_name", "Para's Board");
    env_set("board_rev", "1.0");
    ```
# 注释掉以下内容
#   if (is_mx6ull_9x9_evk())
#       env_set("board_rev", "9X9");
#   else
#       env_set("board_rev", "14X14");
#
#   if (is_cpu_type(MXC_CPU_MX6ULZ)) {
#       env_set("board_name", "ULZ-EVK");
...
    else if (is_cpu_type(MXC_CPU_MX6ULZ))
        puts("Board: MX6ULZ 14x14 EVK\n");
    else
        puts("Board: MX6ULL 14x14 EVK\n");
        puts("Board: Para's MX6ULL board\n");
  • 修改完成后,编译uboot
bash 复制代码
devtool build u-boot-imx
  • 编译通过后,保存当前修改并 git commit, 然后生成patch
bash 复制代码
git add -A
git commit -m "create imx6ull-14x14-evk-emmc.dts"

devtool finish --force-patch-refresh u-boot-imx /home/yoctouser/yocto-build/imx-yocto/sources/meta-myboard
# 这一步会自动创建 类似 0001-create-imx6ull-14x14-evk-emmc.dts.patch 文件
# 并 把这个文件导入 /home/yoctouser/yocto-build/imx-yocto/sources/meta-myboard/recipes-bsp/u-boot/files/

2.3 u-boot-imx_%.bbappend

上一步执行完成以后,生成的patch 文件会自动加入 u-boot/u-boot-imx_%.bbappend

bash 复制代码
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SRC_URI += "file://0001-create-imx6ull-14x14-evk-emmc.dts.patch \
            "

2.4 编译及烧录 uboot

bash 复制代码
# 编译新的镜像
bitbake my-imx6ull-image
# 查看新镜像
cd /home/${user}/yocto-build/imx-yocto/build-myboard/tmp/deploy/images/my-imx6ull
ls
# 编译成功后,把新的镜像烧录到sd卡
unzstd my-imx6ull-image-my-imx6ull.rootfs-${yyyymmddhhmmss}.wic.zst
# 假设SD卡的 device 名是 /dev/sdb
sudo umount /dev/sdb1
sudo umount /dev/sdb2
sudo dd if=my-imx6ull-image-my-imx6ull.rootfs-20261012074922.wic of=/dev/sdb bs=4M status=progress conv=fsync
sync
2.5 在 imx6ull 上验证新的修改
  • 先确认 U-Boot 当前加载的是哪一个 .dtb
  • 找到设备树在内存中的地址
  • 用 U-Boot 的 fdt 命令查看根节点属性
  • 必要时直接打印完整设备树里的关键节点
bash 复制代码
# 以下是 uboot 启动log

U-Boot 2024.04-lf_v2024.04+g6c4545203d1+p0 (Nov 15 2024 - 04:02:13 +0000)

CPU:   i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 30C
Reset cause: POR
Model: Para's i.MX6 ULL Board in U-Boot
Board: Para's MX6ULL board
DRAM:  512 MiB

...
...
...

=> mmc list
FSL_SDHC: 0 (SD)
FSL_SDHC: 1
=> fatls mmc 0:1
    36525   my-imx6ull-emmc.dtb
   408328   tee.bin
   408392   uTee-6ullevk
  9476032   zImage

4 file(s), 0 dir(s)

=> printenv myfdt_file
myfdt_file=my-imx6ull-emmc.dtb
=>
myfdt_file=my-imx6ull-emmc.dtb
=> printenv fdt_addr
fdt_addr=0x83000000
=> load mmc 0:1 0x83000000 myfdt_file
Failed to load 'myfdt_file'
=> load mmc 0:1 0x83000000 ${myfdt_file}
36525 bytes read in 6 ms (5.8 MiB/s)
=> fdt print /
No FDT memory address configured. Please configure
the FDT address via "fdt addr <address>" command.
Aborting!
=> fdt addr ${fdt_addr}
Working FDT set to 83000000
=>
=> fdt print / model
model = "Freescale i.MX6 ULL 14x14 EVK Board, my board(Para's board)"
=> fdt print / compatible
compatible = "myboard,imx6ull-14x14-evk", "fsl,imx6ull"
=>
相关推荐
恒锐丰科技林技术员40 分钟前
EG2132 半桥栅极驱动芯片解析:高压半桥应用的性价比之选
经验分享·嵌入式硬件·硬件工程
梦想的初衷~44 分钟前
CESM2 完整实操学习大纲:环境搭建、案例运行、耦合模拟与代码开发
linux·地球系统模式·cesm2·气候模式模拟·clm 陆面模型·cam 大气模式·模式移植编译
叼烟扛炮1 小时前
Linux 学习笔记(三):文件管理与文本查看
linux·笔记·学习
Iruoyaoxh1 小时前
linux-进程概念
linux
AbandonForce1 小时前
Linux 网络:HTTP(一)基础与报文结构
linux·网络·http
尼喃1 小时前
3.7V升压5V芯片——平芯微PW5100/PW5300/PW5300A/PW6276/PW5303/PW5012
嵌入式硬件
意法半导体STM321 小时前
【官方原创】LAT6041 STM32MP1x USB OTG FIFO设置
stm32·单片机·嵌入式硬件·mcu·fifo·stm32mp1x
笨笨饿1 小时前
#145 _Codex 三层故障详细排查与修复步骤
开发语言·人工智能·stm32·单片机·嵌入式硬件
传感器与混合集成电路1 小时前
多通道伺服数据采集模块国产ADC 16位同步采样与运放调理设计
嵌入式硬件