Yocto 构建基于官方 imx6ull-14x14-evk 的customer镜像
这篇文章主要介绍:
- 搭建 ubuntu + docker + yocto 的开发环境
- Yocto 中创建自定义 layer,并集成到构建系统
- 基于官方 machine 配置,创建自定义 machine(如 my-imx6ull),并指定自定义的设备树(Device Tree)和 U-Boot 配置
- 通过 patch 或直接替换的方式,定制和集成自己的设备树源码到 Yocto 构建流程中
- 编译、烧录并在目标 i.MX6ULL 硬件上验证自定义镜像和设备树的生效,包括在 U-Boot 阶段检查 model 和 compatible 属性。
0. 首先进入 docker 虚拟机并初始化 yocto环境
# 进入dockerdockerrun-it--rm\--security-optseccomp=unconfined\--nameyocto-imx6ull\-v~/yocto-build:/home/yoctouser/yocto-build\-v~/.ssh:/home/yoctouser/.ssh:ro\-v/etc/localtime:/etc/localtime:ro\--dns114.114.114.114\yocto-imx6ull:22.04 /bin/bashcd~/yocto-build/imx-yocto# 使用 Yocto 提供的脚本创建 layer 骨架# initialize environmentsourceimx-setup-release.sh-bbuild1. 创建自定义 layer
bitbake-layers create-layer../sources/meta-myboard这会生成 meta-myboard/ 目录结构。然后使能该 layer:
# 方式 1:手动编辑 bblayers.confbitbake-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 文件sourceimx-setup-release.sh-bbuild_my_imx6ull2. 创建新的 Machine 配置
这是最关键的一步。创建一个新的 machine(例如 my-imx6ull),继承 imx6ull14x14evk 的所有默认配置,再针对性覆盖。
2.1. 创建 machine 文件
mkdir-psources/meta-myboard/conf/machinecat>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" EOF2.2 修改 Device Tree
注意:
以下有2个设备树: - my_imx6ull_emmc.dts:uboot 使用的设备树 - my-imx6ull-emmc.dts: kernel 使用的设备树, 由 uboot 加载硬件差异 90% 体现在 Device Tree 上:引脚复用(pinctrl)、外设节点(UART/SPI/I2C/ETH)、regulator、时钟等。
创建 bsp recipe, 路径: yocto-build/imx-yocto/sources/meta-myboard/recipes-bsp/u-boot/
目录结构:
- 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 环境
dockerrun-it--rm\--security-optseccomp=unconfined\--nameyocto-imx6ull\-v~/yocto-build:/home/yoctouser/yocto-build\-v~/.ssh:/home/yoctouser/.ssh:ro\-v/etc/localtime:/etc/localtime:ro\--dns114.114.114.114\yocto-imx6ull:setup_git /bin/bashcd~/yocto-build/imx-yoctoMACHINE=my-imx6ullDISTRO=fsl-imx-fbsource./imx-setup-release.sh-bbuild-myboard- 进入 uboot 的开发环境
devtool modify u-boot-imx# 此时会在 /home/yoctouser/yocto-build/imx-yocto/build-myboard/workspace/sources# 路径下出现 uboot的源码- 创建 my_imx6ull_emmc.dts
# 在 uboot的源码里 copy 官方设备树为 my_imx6ull_emmc.dtscd/home/yoctouser/yocto-build/imx-yocto/build-myboard/workspace/sources/ubootcdarch/arm/dts/cpimx6ull-14x14-evk-emmc.dts my_imx6ull_emmc.dts- 修改 my_imx6ull_emmc.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) += 处加上新的设备树
dtb-$(CONFIG_MX6ULL)+=imx6ulz-bsh-smm-m2.dtb\imx6ulz-14x14-evk.dtb\imx6ulz-14x14-evk-emmc.dtb\my_imx6ull_emmc.dtb- 在 uboot 里指定 kernel 使用的设备树 my-imx6ull-emmc.dts
修改 include/configs/mx6ullevk.h
"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
# 在函数 int board_late_init(void) 里...#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIGenv_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");...elseif(is_cpu_type(MXC_CPU_MX6ULZ))puts("Board: MX6ULZ 14x14 EVK\n");elseputs("Board: MX6ULL 14x14 EVK\n");puts("Board: Para's MX6ULL board\n");- 修改完成后,编译uboot
devtool build u-boot-imx- 编译通过后,保存当前修改并 git commit, 然后生成patch
gitadd-Agitcommit-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
FILESEXTRAPATHS:prepend :="${THISDIR}/files:"SRC_URI+="file://0001-create-imx6ull-14x14-evk-emmc.dts.patch \ "2.4 编译及烧录 uboot
# 编译新的镜像bitbake my-imx6ull-image# 查看新镜像cd/home/${user}/yocto-build/imx-yocto/build-myboard/tmp/deploy/images/my-imx6ullls# 编译成功后,把新的镜像烧录到sd卡unzstd my-imx6ull-image-my-imx6ull.rootfs-${yyyymmddhhmmss}.wic.zst# 假设SD卡的 device 名是 /dev/sdbsudoumount/dev/sdb1sudoumount/dev/sdb2sudoddif=my-imx6ull-image-my-imx6ull.rootfs-20261012074922.wicof=/dev/sdbbs=4Mstatus=progressconv=fsyncsync2.5 在 imx6ull 上验证新的修改
- 先确认 U-Boot 当前加载的是哪一个 .dtb
- 找到设备树在内存中的地址
- 用 U-Boot 的 fdt 命令查看根节点属性
- 必要时直接打印完整设备树里的关键节点
# 以下是 uboot 启动logU-Boot2024.04-lf_v2024.04+g6c4545203d1+p0(Nov152024- 04:02:13 +0000)CPU: i.MX6ULL rev1.1792MHz(running at396MHz)CPU: Industrial temperature grade(-40C to 105C)at 30C Reset cause: POR Model: Para's i.MX6 ULL Board in U-Boot --> **这是 "my_imx6ull_emmc.dts" 里 model 的内容** Board: Para's MX6ULL board -->**这是"mx6ullevk.c"里修改后的内容** DRAM:512MiB......... ** 以下是要加载的 kernel 的内容, 在下一篇介绍**=>mmc list FSL_SDHC:0(SD)FSL_SDHC:1=>fatls mmc0:136525my-imx6ull-emmc.dtb408328tee.bin408392uTee-6ullevk9476032zImage4file(s),0dir(s)=>printenvmyfdt_filemyfdt_file=my-imx6ull-emmc.dtb=>myfdt_file=my-imx6ull-emmc.dtb=>printenvfdt_addrfdt_addr=0x83000000=>load mmc0:1 0x83000000 myfdt_file Failed to load'myfdt_file'=>load mmc0:1 0x83000000${myfdt_file}36525bytesreadin6ms(5.8MiB/s)=>fdt print / No FDT memory address configured. Please configure the FDT address via"fdt addr <address>"command. Aborting!=>fdt addr${fdt_addr}Working FDTsetto83000000=>=>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"=>