这篇文章主要介绍 imx6ull 的 bring up:
- 搭建 ubuntu + docker + yocto 的开发环境
- Yocto 中创建自定义 layer,并集成到构建系统
- 基于官方 machine 配置,创建自定义 machine(如 my-imx6ull),并指定自定义的设备树(Device Tree)和 U-Boot 配置
- 通过 patch 或直接替换的方式,定制和集成自己的设备树源码到 Yocto 构建流程中
- 编译、烧录并在目标 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"
=>