开发平台:Ubuntu 18.04.6

目标平台:imx-6ull

uboot 版本:uboot-imx-imx_v2020.04_5.4.70_2.3.0

编译工具链:gcc versions 10.3.1 20210621 (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29))

# 环境搭建

# 交叉编译器

在 ARM 官方链接下载 Arm A-profile architecture 编译工具链,选择自己相应的平台,这里的话是: gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf

解压添加至本地:

# 创建存放编译工具链的文件夹
sudo mkdir /usr/local/arm
# 移动文件
sudo mv gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz /usr/local/arm/
# 解压文件
sudo tar -xvf /usr/local/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz

添加环境变量:

# 添加到系统环境变量 (对所有用户有效)
sudo vim /etc/profile
export PATH=$PATH:/usr/local/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin
# 添加到用户环境变量 (仅对当前用户有效)
sudo vim ~/.bashrc 
export PATH=$PATH:/usr/local/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin
# 以上二选一

测试命令:

# 成功打印版本信息则为通过
arm-none-linux-gnueabihf-gcc -v

# uboot 源码

NXP 维护的 uboot 仓库地址:https://github.com/nxp-imx/uboot-imx

获取 NXP uboot 5.4.70_2.3.0 版本的源码:

# 拉取源码文件
git clone https://github.com/nxp-imx/uboot-imx.git
# 切换到
git checkout imx_v2020.04_5.4.70_2.3.0

上面的 clone 操作会拉取所有分支文件及历史提交信息下来,文件比较大,如果网络不太好,可以尝试打开 https://github.com/nxp-imx/uboot-imx/tree/imx_v2020.04_5.4.70_2.3.0 只下载 ZIP 压缩包下来,然后利用 unzip 命令解压。

或者使用 git clone -b imx_v2020.04_5.4.70_2.3.0 https://github.com/nxp-imx/uboot-imx.git 直接下载指定版本。

note:对于不同分支,有 fslcimx 关键字的区分,以下摘录解释:

There are two BSPs, the BSP Releases which are supported by NXP and their documentation can be found on the Linux i.MX webpage, and the Community BSP.
A BSP Release roadmap is not publicly available, but as you may see there are new BSPs every several months. However, it usually lags in respect to the Linux Mainline Kernel as a lot of work is done to ensure that the kernel works correctly on the NXP hardware. The kernel from these BSP Releases (linux-imx) can be found on the following repository and it is indeed an upstream from the Community BSP Kernel.
https://source.codeaurora.org/external/imx/linux-imx/
As for the Community BSP, it’s constantly being updated by the Community but due to its nature is hard to predict how fast each branch will be developed.
You can find more information about the Community BSP on the link below:
http://freescale.github.io/
The Kernel recipes of the community BSP (linux-fslc) would be on the meta-freescale layer:
http://git.yoctoproject.org/cgit/cgit.cgi/meta-freescale

简单的来讲,就是 imx 是官方发行版,而 fslc 是社区发行版。

来源:https://community.nxp.com/t5/i-MX-Processors/what-is-the-purpose-of-linux-fslc-git/m-p/1047602

关于 uboot 版本选择:

随着时间的变化,uboot 的更新也出现了多个的版本,那么到底应该选择哪一个呢?有些人可能会说当然是越新越好啦。其实呢不是这个样子的,虽然 uboot 本身是在不断的开发和进化当中,但对于新版本来说,可能开发者们在某一个版本中加入了一些新的特性,然后呢过了一段时间又发现这个新功能不是很稳定,就有可能会把它删掉或者需要后期继续更新迭代修复;这样一来就会对我们所移植的 uboot 来说就会增加很多不必要的复杂性,因为不排除是否会影响到所使用的功能,所以一般的原则就是够用就可以了,不需要频繁更新。

那如何选择属于自己的版本呢:

  1. 打开下载的 uboot 目录下的: arch/arm/cpu 目录,确认使用的 cpu 型号是否支持及对应。

  2. 打开 uboot 目录下的: board 目录,查看相对应的外设是否都支持。eq: board/freescale/mx6ull_board/

一般来说,uboot 版本越新支持的开发板和 cpu 就越多,代码量就越多,如果我们的 cpu 和开发板的并没有这么多东西,那我们可以不用新的。而用适合自己产品外设的,通常是根据开发板发行的日期和 uboot 的更新日期来找到合适的 uboot。

# 编译验证

sudo -s
export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabihf-
make distclean
make mx6ull_14x14_evk_emmc_defconfig
make

编译源码这一步的目的:

  • 一是为了验证编译环境是否正常;
  • 二是为了下一步移植过程中的代码分析(一些文件只有在编译后才会生成)。

note:

make clean - 清除了目标机器上可以运行的 bin 文件以及目录,还有中间的过程文件和编译日志,但是会保留内核的配置文件 .config 以及编译支持的扩展模块;

make mrproper - 在 clean 的基础上,清除了交叉编译工具链、menuconfig 的内容;

make distclean - 在 mrproper 的基础上,删除编辑器备份和补丁文件。

删除的文件范围从小到大依次为: make clean < make mrproper < make distclean

注意:

若是提示 make: 未找到命令 ,则需要安装 make 工具:

sudo apt install make

若是出现 /bin/sh: 1: cc: not found ,需要安装 gcc 依赖,因为 HOSTCC scripts/basic/fixdep 强制定义使用了 gcc, HOSTCC=gcc

sudo apt install gcc

若是在系统上第一次编译 uboot 源码可能会遇到缺少 bisonflex 的报错信息导致编译失败,只需安装相应的工具包后重新执行编译即可:

# 语法分析工具
sudo apt install bison
# 词法分析工具
sudo apt install flex

最后再次编译验证,最后得到主目录下的 u-boot-dtb.imx 镜像文件。

# 移植

下面以命名为 lanjut 的板子为例。

# 开发板文件夹

ls -d board/freescale/*6ull*
board/freescale/mx6ullevk     board/freescale/mx6ull_ddr3_val
cp -r board/freescale/mx6ullevk/ board/freescale/mx6ull_lanjut/
mv board/freescale/mx6ull_lanjut/mx6ullevk.c board/freescale/mx6ull_lanjut/mx6ull_lanjut.c
ls board/freescale/mx6ull_lanjut/
imximage.cfg         Kconfig      Makefile        plugin.S
imximage_lpddr2.cfg  MAINTAINERS  mx6ull_lanjut.c  README

修改:

1、 Kconfig 文件:

vim board/freescale/mx6ull_lanjut/Kconfig

更改内容为(注意该文件 endif 后面必须有换行):

if TARGET_MX6ULL_14X14_LANJUT
config SYS_BOARD
	default "mx6ull_lanjut"
config SYS_VENDOR
	default "freescale"
config SYS_CONFIG_NAME
	default "mx6ull_lanjut"
config SYS_TEXT_BASE
	default 0x87800000
endif

2、 Makefile 文件:

vim board/freescale/mx6ull_lanjut/Makefile

obj-y := mx6ullevk.o 改为 obj-y := mx6ull_lanjut.o

3、 imximage_lpddr2.cfgimximage.cfg 文件:

vim board/freescale/mx6ull_lanjut/imximage_lpddr2.cfg
vim board/freescale/mx6ull_lanjut/imximage.cfg

该更改受控于 CONFIG_USE_IMXIMG_PLUGIN 宏定义,在配置文件中是没有使能的,改不改都无所谓,但为了统一,把 PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000 改为 PLUGIN board/freescale/mx6ull_lanjut/plugin.bin 0x00907000

4、 MAINTAINERS 文件:

vim board/freescale/mx6ull_lanjut/MAINTAINERS

是维护者记录文件,作为个人使用,改不改都无所谓;如果是作为 uboot 项目维护者,则需要完整记录好详细的信息,以便更好的发展维护。

MX6ULL_LANJUT BOARD
M:	Arachnid <xxxx@qq.com>
S:	Maintained
F:	board/freescale/mx6ull_lanjut/
F:	include/configs/mx6ull_lanjut.h
F:	configs/mx6ull_14x14_lanjut_defconfig
F:	configs/mx6ull_14x14_lanjut_plugin_defconfig
F:	configs/mx6ulz_14x14_lanjut_defconfig

5、 mx6ull_lanjut.c 文件:

vim board/freescale/mx6ull_lanjut/mx6ull_lanjut.c
  • board_late_init 函数

    int board_late_init(void)
    {
    #ifdef CONFIG_CMD_BMODE
    	add_board_boot_modes(board_boot_modes);
    #endif
    	env_set("tee", "no");
    #ifdef CONFIG_IMX_OPTEE
    	env_set("tee", "yes");
    #endif
    #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    	env_set("board_name", "LANJUT");	// 决定了后面 findfdt 和 findtee 环境变量的选择
    	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");
    		env_set("usb_net_cmd", "usb start");
        }
    #endif
    	setup_lcd();
    #ifdef CONFIG_ENV_IS_IN_MMC
    	board_late_mmc_env_init();
    #endif
    	set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR);
    	return 0;
    }
  • checkboard 函数

    int checkboard(void)
    {
    	if (is_mx6ull_9x9_evk())
    		puts("Board: MX6ULL 9x9 EVK\n");
    	else if (is_cpu_type(MXC_CPU_MX6ULZ))
    		puts("Board: MX6ULZ 14x14 EVK\n");
    	else
    		puts("Board: MX6ULL 14x14 LANJUT\n");	//uboot 板载信息显示
    	return 0;
    }

# 设备树文件

在新版本 uboot 中,参考 Linux 内核引入了设备树驱动模型 (Driver Model)

1、 imx6ull-14x14-lanjut-emmc.dts 文件:

ls arch/arm/dts/*6ull*.dts
arch/arm/dts/imx6ull-14x14-ddr3-val.dts
arch/arm/dts/imx6ull-14x14-ddr3-val-emmc.dts
arch/arm/dts/imx6ull-14x14-ddr3-val-epdc.dts
arch/arm/dts/imx6ull-14x14-ddr3-val-gpmi-weim.dts
arch/arm/dts/imx6ull-14x14-ddr3-val-lcdif.dts
arch/arm/dts/imx6ull-14x14-ddr3-val-tsc.dts
arch/arm/dts/imx6ull-14x14-evk.dts
arch/arm/dts/imx6ull-14x14-evk-emmc.dts
arch/arm/dts/imx6ull-14x14-evk-gpmi-weim.dts
arch/arm/dts/imx6ull-9x9-evk.dts
arch/arm/dts/imx6ull-colibri.dts
arch/arm/dts/imx6ull-dart-6ul.dts
arch/arm/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts
arch/arm/dts/imx6ull-somlabs-visionsom.dts
cp arch/arm/dts/imx6ull-14x14-evk-emmc.dts arch/arm/dts/imx6ull-14x14-lanjut-emmc.dts
vim arch/arm/dts/imx6ull-14x14-lanjut-emmc.dts

修改:

#include "imx6ull-14x14-evk.dts" 更改为 #include "imx6ull-14x14-lanjut.dts"

2、 imx6ull-14x14-lanjut.dts 文件:

cp arch/arm/dts/imx6ull-14x14-evk.dts arch/arm/dts/imx6ull-14x14-lanjut.dts
vim arch/arm/dts/imx6ull-14x14-lanjut.dts

修改:

#include "imx6ul-14x14-evk.dtsi" 更改为 #include "imx6ul-14x14-lanjut.dtsi"

#include "imx6ul-14x14-evk-u-boot.dtsi" 更改为 #include "imx6ul-14x14-lanjut-u-boot.dtsi"

同时更改以下内容:

/ {
	model = "i.MX6 ULL 14x14 EVK Board";
	compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
};
改为
/ {
	model = "i.MX6 ULL 14x14 LANJUT Board";
	compatible = "fsl,imx6ull-14x14-lanjut", "fsl,imx6ull";
};

3、 imx6ul-14x14-lanjut.dtsiimx6ul-14x14-lanjut-u-boot.dtsi 文件:

根据 imx6ull-14x14-lanjut.dts 文件的 #include 包含文件,分别添加文件。

cp arch/arm/dts/imx6ul-14x14-evk.dtsi arch/arm/dts/imx6ul-14x14-lanjut.dtsi
cp arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi arch/arm/dts/imx6ul-14x14-lanjut-u-boot.dtsi

# 配置文件

1、 mx6ull_14x14_lanjut_emmc_defconfig 文件:

ls configs/*6ull*
configs/colibri-imx6ull_defconfig
configs/mx6ull_14x14_ddr3_val_defconfig
configs/mx6ull_14x14_ddr3_val_emmc_defconfig
configs/mx6ull_14x14_ddr3_val_epdc_defconfig
configs/mx6ull_14x14_ddr3_val_nand_defconfig
configs/mx6ull_14x14_ddr3_val_plugin_defconfig
configs/mx6ull_14x14_ddr3_val_qspi1_defconfig
configs/mx6ull_14x14_ddr3_val_spinor_defconfig
configs/mx6ull_14x14_ddr3_val_tsc_defconfig
configs/mx6ull_14x14_evk_defconfig
configs/mx6ull_14x14_evk_emmc_defconfig
configs/mx6ull_14x14_evk_nand_defconfig
configs/mx6ull_14x14_evk_optee_defconfig
configs/mx6ull_14x14_evk_plugin_defconfig
configs/mx6ull_14x14_evk_qspi1_defconfig
configs/mx6ull_9x9_evk_defconfig
configs/mx6ull_9x9_evk_plugin_defconfig
configs/mx6ull_9x9_evk_qspi1_defconfig
configs/somlabs_visionsom_6ull_defconfig
cp configs/mx6ull_14x14_evk_emmc_defconfig configs/mx6ull_14x14_lanjut_emmc_defconfig
vim configs/mx6ull_14x14_lanjut_emmc_defconfig

修改:

CONFIG_TARGET_MX6ULL_14X14_EVK=y 改为 CONFIG_TARGET_MX6ULL_14X14_LANJUT=y

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullevk/imximage.cfg" 改为 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_lanjut/imximage.cfg"

CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-evk-emmc" 改为 CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-lanjut-emmc"

2、 include/configs/mx6ull_lanjut.h 文件:

ls include/configs/*6ull*
include/configs/colibri-imx6ull.h  include/configs/mx6ullevk.h
include/configs/mx6ull_ddr3_val.h  include/configs/somlabs_visionsom_6ull.h
cp include/configs/mx6ullevk.h include/configs/mx6ull_lanjut.h
vim include/configs/mx6ull_lanjut.h

修改:

#ifndef __MX6ULLEVK_CONFIG_H#define __MX6ULLEVK_CONFIG_H 改为 #ifndef __MX6ULL_LANJUT_CONFIG_H#define __MX6ULL_LANJUT_CONFIG_H

更改 uboot 默认命令配置值:

  • findfdt(用于设置 fdt_file 变量,根据 board_name 来指定传递给内核的设备树文件名)

    "findfdt="\
    			"if test $fdt_file = undefined; then " \
    				"if test $board_name = ULZ-EVK && test $board_rev = 14X14; then " \
    					"setenv fdt_file imx6ulz-14x14-evk.dtb; fi; " \
    				"if test $board_name = EVK && test $board_rev = 9X9; then " \
    					"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
    				"if test $board_name = EVK && test $board_rev = 14X14; then " \
    					"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
    				"if test $board_name = LANJUT && test $board_rev = 14X14; then " \
    					"setenv fdt_file imx6ull-14x14-lanjut.dtb; fi; " \
    				"if test $fdt_file = undefined; then " \
    					"echo WARNING: Could not determine dtb to use; " \
    				"fi; " \
    			"fi;\0" \
  • findtee(用于设置 tee_file 变量,根据 board_name 来指定 uboot 设备树文件名)

    "findtee="\
    			"if test $tee_file = undefined; then " \
    				"if test $board_name = ULZ-EVK && test $board_rev = 14X14; then " \
    					"setenv tee_file uTee-6ulzevk; fi; " \
    				"if test $board_name = EVK && test $board_rev = 9X9; then " \
    					"setenv tee_file uTee-6ullevk; fi; " \
    				"if test $board_name = EVK && test $board_rev = 14X14; then " \
    					"setenv tee_file uTee-6ullevk; fi; " \
    				"if test $board_name = LANJUT && test $board_rev = 14X14; then " \
    					"setenv tee_file uTee-6ull_lanjut; fi; " \
    				"if test $tee_file = undefined; then " \
    					"echo WARNING: Could not determine tee to use; " \
    				"fi; " \
    			"fi;\0" \

# 其它文件

1、 Makefile 文件:

vim arch/arm/dts/Makefile

修改:

dtb-$(CONFIG_MX6ULL) += \
	imx6ull-14x14-ddr3-val.dtb \
	imx6ull-14x14-ddr3-val-epdc.dtb \
	imx6ull-14x14-ddr3-val-emmc.dtb \
	imx6ull-14x14-ddr3-val-gpmi-weim.dtb \
	imx6ull-14x14-ddr3-val-tsc.dtb \
	imx6ull-14x14-evk.dtb \
	imx6ull-14x14-evk-emmc.dtb \
	imx6ull-14x14-evk-gpmi-weim.dtb \
	imx6ull-14x14-lanjut-emmc.dtb \  # 将设备树文件添加进编译项
	imx6ull-9x9-evk.dtb \
	imx6ull-colibri.dtb \
	imx6ull-phytec-segin-ff-rdk-emmc.dtb \
	imx6ull-dart-6ul.dtb \
	imx6ull-somlabs-visionsom.dtb \
	imx6ulz-14x14-evk.dtb \
	imx6ulz-14x14-evk-emmc.dtb \
	imx6ulz-14x14-evk-gpmi-weim.dtb

2、 Kconfig 文件:

vim arch/arm/mach-imx/mx6/Kconfig

修改:

config TARGET_MX6ULL_14X14_EVK 配置的下方添加:

config TARGET_MX6ULL_14X14_LANJUT
	bool "Support mx6ull_14x14_lanjut"
	select BOARD_LATE_INIT
	select DM
	select DM_THERMAL
	select MX6ULL
	imply CMD_DM

source "board/freescale/mx6ullevk/Kconfig" 配置的下方添加:

source "board/freescale/mx6ull_lanjut/Kconfig"

# 定制外设

# 移除 74lv595 芯片相关配置

1、 mx6ull_14x14_lanjut_emmc_defconfig 文件:

vim configs/mx6ull_14x14_lanjut_emmc_defconfig

由于开发板上不需要用到 74lv595 芯片,因此取消与其相关的配置:

  • 找到 CONFIG_DM_74X164=y 改为 # CONFIG_DM_74X164 is not used ,官网 EVK 开发板使用了一个 74LV594,这里没有使用所以屏蔽掉。
  • 找到 CONFIG_SOFT_SPI=y 改为 # CONFIG_SOFT_SPI is not used ,屏蔽掉软件模拟的 SPI,这是官方驱动 74LV594 用的,同样也是用不到。

2、 imx6ul-14x14-lanjut.dtsi 文件:

vim arch/arm/dts/imx6ul-14x14-lanjut.dtsi

configs/mx6ull_14x14_lanjut_emmc_defconfig 文件中,我们有屏蔽掉 74LV594软件模拟的 SPI 的定义使用,因此在设备树操作这里同样把其相关的配置屏蔽掉,从它们的调用关系可以得到以下需要屏蔽:

/ {
	// aliases {
	// 	spi5 = &{/spi4};
	// };
	// reg_can_3v3: regulator-can-3v3 {
	// 	compatible = "regulator-fixed";
	// 	regulator-name = "can-3v3";
	// 	regulator-min-microvolt = <3300000>;
	// 	regulator-max-microvolt = <3300000>;
	// 	gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
	// };
	// spi4 {
	// 	compatible = "spi-gpio";
	// 	pinctrl-names = "default";
	// 	pinctrl-0 = <&pinctrl_spi4>;
	// 	status = "okay";
	// 	pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
	// 	gpio-sck = <&gpio5 11 0>;
	// 	gpio-mosi = <&gpio5 10 0>;
	// 	cs-gpios = <&gpio5 7 0>;
	// 	num-chipselects = <1>;
	// 	#address-cells = <1>;
	// 	#size-cells = <0>;
	// 	gpio_spi: gpio@0 {
	// 		compatible = "fairchild,74hc595";
	// 		gpio-controller;
	// 		#gpio-cells = <2>;
	// 		reg = <0>;
	// 		registers-number = <1>;
	// 		registers-default = /bits/ 8 <0x57>;
	// 		spi-max-frequency = <100000>;
	// 	};
	// };
};
&can1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_flexcan1>;
	// xceiver-supply = <&reg_can_3v3>;
	status = "okay";
};
&can2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_flexcan2>;
	// xceiver-supply = <&reg_can_3v3>;
	status = "okay";
};
&iomuxc {
	pinctrl-names = "default";
	// pinctrl_spi4: spi4grp {
	// 	fsl,pins = <
	// 		MX6UL_PAD_BOOT_MODE0__GPIO5_IO10	0x70a1
	// 		MX6UL_PAD_BOOT_MODE1__GPIO5_IO11	0x70a1
	// 		MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07	0x70a1
	// 		MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08	0x80000000
	// 	>;
	// };
};

# 修改网络接口配置

打开你的设备树文件 arch/arm/dts/imx6ull-14x14-lanjut-emmc.dts ,可以看到相应的引用关系: imx6ull-14x14-lanjut-emmc.dts -> imx6ull-14x14-lanjut.dts -> imx6ull.dtsi -> imx6ul-14x14-lanjut.dtsi -> imx6ul-14x14-lanjut-u-boot.dtsi 。而一般来说, .dtsi 是系列芯片的公共部分,如同 C 语言上的头文件一般, .dts 则用于定义特定部分;同样的,对于已经在 .dtsi 定义过的节点,可以在 .dts 中重新定义并覆盖。

在 imx6ull 中,共提供了两组 ETH 网络接口引脚,在这里只需要配置一组就好了,多了没必要;可能你也会觉得 uboot 阶段只是为了引导 kernel 启动,何必多此一举呢,毕竟真正执行的配置是在 kernel 中的属性配置,但你是否想过后期如果需要修改 kernel,那么在此操作前,你能进行的 kernel 更新就只有 OTG 烧录及 SD Card 更新,并且需要拨码,相对于网络更新,稍微复杂一点,而且像 SD Card 你也未必携带有;因此,既然在 uboot 中存在一个如此便捷的升级方式,为何不好好应用起来呢?

前面讲了 imx6ull 提供了两组 ETH 网络接口引脚,因此,只要有引出 ETH 接口,那么它们必定成组配置,所以无论你是用 eth0 或是 eth1 或想两组都用,在官方 demo 中一般都存在着对应组的设备树节点,可能唯一区别是 eth0eth1 对应哪一组、PHY 地址不一样及网络芯片复位引脚所关联 GPIO 之类的;而且,对于用户设计来讲,一般都是跟官方的设计大同小异,没必要大改动以至于重新适配调试整个设备树配置及驱动修改,对此在这里以 eth1 、PHY 地址为 0x01 为例:

1、查阅关联信息

翻看芯片参考手册,找到与网络相关的章节,可以看到官方主要命名为 ENET;接下来在设备树中,包括引用的设备树头文件 .dtsi 里面搜索 enet ,能找到名为 &fecx 的设备树节点,这些节点信息就是对网络接口的配置。

2、节点属性

网络设备树节点属性,在这里可以根据自己所使用的 uboot 版本日期,去 https://www.devicetree.org/specifications 里找附近时期的文档查看;还有一种方式是在 doc/device-tree-bindings/net/ 路径下查找相关的信息;不过不管是以上哪种方式,大部分也只是给出参考,实际需根据设备树函数处理来分析具体参数效果。

3、功能配置修改

在简单了解相关的信息后,然后就可以开始操刀修改配置了。

...
&fec1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet1>;
	phy-mode = "rmii";
	phy-handle = <&ethphy0>;
	status = "okay";
};
&fec2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet2>;
	phy-mode = "rmii";
	phy-handle = <&ethphy1>;
	status = "okay";
	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		ethphy0: ethernet-phy@2 {
			reg = <2>;
			micrel,led-mode = <1>;
			clocks = <&clks IMX6UL_CLK_ENET_REF>;
			clock-names = "rmii-ref";
		};
		ethphy1: ethernet-phy@1 {
			reg = <1>;
			micrel,led-mode = <1>;
			clocks = <&clks IMX6UL_CLK_ENET2_REF>;
			clock-names = "rmii-ref";
		};
	};
};
...

以上是相关的原有功能配置,然后 eth0 对应 &fec1eth1 对应 &fec2 ,在这里只应用 eth1 ,因此在 &fec1 中把 status 参数改成 disable 以关闭该项功能;紧接着如果你的 PHY 芯片复位引脚是引接到芯片上控制而非复位按键上,那么你应该需要添加对 PHY 芯片复位的控制:

&fec2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet2>;
	phy-mode = "rmii";
	phy-handle = <&ethphy1>;
	phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
	phy-reset-duration = <10>;
	phy-reset-post-delay = <10>;
	status = "okay";
	...
};

&fec2 节点中,加入 phy-reset-gpios 参数指定 PHY 的复位引脚且说明低电平复位, phy-reset-duration 指定复位的持续时间, phy-reset-post-delay 指定复位延迟时间。

在官方设备树里面, eth0 的 PHY 地址配置为 2、 eth 的 PHY 地址配置为 1,如果需要修改 PHY 地址,则可以在 mdio 里的 ethphyx 中的 reg 属性里更改为硬件设计上的 PHY 地址,然后为了统一标准,把 ethernet-phy@x@xx 改为 reg 上的数值(当然,你也可以选择不改,这并不会影响什么功能,只是设备树作为一份适合人类阅读的文本文件,影响到的是后期的阅读分析),在这里因为设计地址跟官方一样, eth1 的 PHY 地址为 1,因此不需要修改:

&fec2 {
	...
	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		ethphy0: ethernet-phy@2 {
			reg = <2>;
			micrel,led-mode = <1>;
			clocks = <&clks IMX6UL_CLK_ENET_REF>;
			clock-names = "rmii-ref";
		};
		ethphy1: ethernet-phy@1 {	// 标识 PHY 地址为 1
			reg = <1>;	// PHY 地址设置为 1
			micrel,led-mode = <1>;
			clocks = <&clks IMX6UL_CLK_ENET2_REF>;
			clock-names = "rmii-ref";
		};
	};
};

4、复位引脚配置

A、配置分析

...
&iomuxc {
	pinctrl-names = "default";
	...
	pinctrl_enet1: enet1grp {
		fsl,pins = <
			MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN	0x1b0b0
			MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER	0x1b0b0
			MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00	0x1b0b0
			MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01	0x1b0b0
			MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN	0x1b0b0
			MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00	0x1b0b0
			MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01	0x1b0b0
			MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1	0x4001b031
		>;
	};
	pinctrl_enet2: enet2grp {
		fsl,pins = <
			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0
			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0
			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031
		>;
	};
	
	...
};
...

在功能配置里为 eth1 的 PHY 芯片添加了复位引脚的操作,因此我们必须对其 IO 进行初始化配置;由于以下修改主要涉及到设备树的引脚配置,因此在修改前先了解一下该芯片设备树中引脚定义规则和解析:

在手册上,一个引脚一般支持 n 个可选功能(Alternate 缩写为 ALT), 通过 IOMUX Controller 的控制器进行选择,IOMUX Controller 由两个子模块组成:

  • IOMUXC_REGISTERS 包括所有的 IOMUXC 寄存器。
  • IOMUXC_LOGIC 包括所有的 IOMUXC 组合逻辑(IP 接口控制、地址解码器、可观察性互斥器)。

而 IOMUXC_REGISTERS 主要通过两个寄存器进行引脚的配置(note:XXX 表示为某一个 PAD 的名称,eg:GPIO1_IO07):

  • IOMUXC_SW_MUX_CTL_PAD_XXX:用于配置引脚 MUX 的输入功能,包括 UART,GPIO,CSI 等功能。

    image-20240728182215737

  • IOMUXC_SW_PAD_CTL_PAD__XXX:用于配置具体功能的特性,包括上拉 / 下拉,速度,等特性。

    image-20240728182843672

在设备树上 imx6u 系列的引脚定义在 arch/arm/dts/imx6ul-pinfunc.h ,6ull 在此基础上追加 imx6ull-pinfunc.himx6ull-pinfunc-snvs.h 定义的扩展性功能引脚,而对于 GPIO1_IO07 的定义涵盖以下几项:

#define MX6UL_PAD_GPIO1_IO07__ENET1_MDC			0x0078 0x0304 0x0000 0 0
#define MX6UL_PAD_GPIO1_IO07__ENET2_MDC			0x0078 0x0304 0x0000 1 0
#define MX6UL_PAD_GPIO1_IO07__USB_OTG_HOST_MODE		0x0078 0x0304 0x0000 2 0
#define MX6UL_PAD_GPIO1_IO07__CSI_PIXCLK		0x0078 0x0304 0x0528 3 0
#define MX6UL_PAD_GPIO1_IO07__USDHC2_CD_B		0x0078 0x0304 0x0674 4 1
#define MX6UL_PAD_GPIO1_IO07__GPIO1_IO07		0x0078 0x0304 0x0000 5 0
#define MX6UL_PAD_GPIO1_IO07__CCM_STOP			0x0078 0x0304 0x0000 6 0
#define MX6UL_PAD_GPIO1_IO07__UART1_DCE_RTS		0x0078 0x0304 0x0620 8 1
#define MX6UL_PAD_GPIO1_IO07__UART1_DTE_CTS		0x0078 0x0304 0x0000 8 0

可以看到 MX6UL_PAD_GPIO1_IO07 是这个引脚的寄存器名称,后面 ENET1_MDC 部分则是对应这个引脚的可选功能(ALTn),然后所定义的参数有 4 个值,而这 4 个值可以在该头文件顶部看到说明:

/*
 * The pin function ID is a tuple of
 * <mux_reg conf_reg input_reg mux_mode input_val>
 */

因此,像 MX6UL_PAD_GPIO1_IO07__ENET2_MDC 这个宏,其定义数值分别表示:

  • mux_reg:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO07 - 偏移地址 0x0078
  • conf_reg:IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO07 - 偏移地址 0x0304
  • input_reg:无寄存器(若有一般为 xxx_SELECT_INPUT) - 偏移地址 0x0000
  • mux_reg:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO07[3:0] - 1(配置成 ALT0 - ENET2_MDC)
  • input_val:由 input_reg 决定是否存在,依据 mux_reg 选择复用 - 0(无 input_reg,此处为 0)

而对于在 dts 中的 MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0 主要是对 conf_reg 的配置,即 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO07 的值为 0x1b0b0 。这些数据的处理可以在 drivers/pinctrl/nxp/pinctrl-imx.c 中查到。至此,得到这样的一个配置关系:

mux_reg_ofsconf_reg_ofsinput_reg_ofsmux_modeinput_valconfig_val
0x00780x03040x0000100x1b0b0

B、追加配置

在了解完如何配置后,然后来配置一个 GPIO5_IO08 引脚的复位操作,草鸡简单,在 pinctrl_enet2 节点上追加 MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 引脚的配置:

...
&iomuxc {
	pinctrl-names = "default";
	...
	pinctrl_enet2: enet2grp {
		fsl,pins = <
			...
			
			MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08	0x898	/* ENET2 NRST */
		>;
	};
	
	...
};
...

# uboot 裁剪

不管是购买的板子还是自己设计的板子,基本都是参考半导体厂商的 demo 板,而半导体厂商会在他们自己的开发板上移植好 uboot、linux kernel 和 rootfs 等,最终制作好 BSP 包提供给用户。我们只需在官方提供的 BSP 包的基础上,修改适应于自己的板子的外设配置,也就是俗称的移植。

一般对 uboot 的移植裁剪。只需要解决串口、NAND、EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot 的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动,剩下的交给 linux kernel 进行详细配置。

如果以单片机思维来讲,Linux 的 uboot 类似于 bootloader ,因此,在 uboot 上不需要过多的配置,只需要确保能正常进入 linux kernel 即可,毕竟进入到 linux kernel 后将会重新根据 linux kernel 的配置再次初始化一遍。

前面讲了,除非必要的外设,把其余的功能移除掉,这便是裁剪;因此像 IIC、SPI、USB 这些等都可以屏蔽掉(或者确认以存储介质启动把网络也禁掉都是可以的),以减少编译生成使得缩少文件大小。

裁剪方式很简单:

1、在 configs/ 文件夹中,找到你的板子配置文件,eg: mx6ull_14x14_lanjut_emmc_defconfig 对不需要的功能进行屏蔽操作:

CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_14X14_LANJUT=y
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xE0000
CONFIG_DM_GPIO=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_lanjut/imximage.cfg"
CONFIG_BOOTDELAY=1
# CONFIG_CONSOLE_MUX is not set
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOUNCE_BUFFER=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_MEMTEST=y
# CONFIG_CMD_GPIO=y
# CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_SF=y
# CONFIG_CMD_USB=y
# CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
# CONFIG_CMD_BMP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_NET=y
# CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-lanjut-emmc"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_74X164 is not used
# CONFIG_DM_I2C=y
CONFIG_DM_MMC=y
CONFIG_FSL_USDHC=y
CONFIG_MTD=y
# CONFIG_DM_SPI_FLASH=y
# CONFIG_SF_DEFAULT_MODE=0
# CONFIG_SF_DEFAULT_SPEED=40000000
# CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHYLIB=y
# CONFIG_PHY_MICREL=y
# CONFIG_PHY_MICREL_KSZ8XXX=y
CONFIG_DM_ETH=y
CONFIG_DM_ETH_PHY=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_IMX6=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
# CONFIG_SPI=y
# CONFIG_DM_SPI=y
# CONFIG_SOFT_SPI is not used
# CONFIG_FSL_QSPI=y
# CONFIG_USB=y
# CONFIG_DM_USB=y
# CONFIG_USB_STORAGE=y
# CONFIG_USB_HOST_ETHER=y
# CONFIG_USB_ETHER_ASIX=y
# CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
# CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DOWNLOAD=y
# CONFIG_USB_GADGET_MANUFACTURER="FSL"
# CONFIG_USB_GADGET_VENDOR_NUM=0x0525
# CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
# CONFIG_CI_UDC=y
# CONFIG_CMD_FASTBOOT=y
# CONFIG_USB_FUNCTION_FASTBOOT=y
# CONFIG_FASTBOOT_UUU_SUPPORT=y
# CONFIG_FASTBOOT=y
# CONFIG_FASTBOOT_BUF_ADDR=0x83800000
# CONFIG_FASTBOOT_BUF_SIZE=0x40000000
# CONFIG_FASTBOOT_FLASH=y
# CONFIG_EFI_PARTITION=y

以上操作主要是裁切不需要的命令行、USB 操作、IIC 功能、SPI 功能、video 功能;当然你也可以通过先 make xxx_defconfig 生成 .config 文件,然后进行 make meunconfig 进入图型交互界面,对不需要的配置进行移除,在这里修改的目的是为了通过执行 make xxx_defconfig 后生成的默认 .config 文件即为裁剪好的配置,而不需要再进行 make meunconfig 选择移除。

2、修改单板配置文件,eg: include/configs/mx6ull_lanjut.h ;该文件主要是配置 uboot env 环境及启动初始化。

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * Configuration settings for the Freescale i.MX6UL 14x14 EVK board.
 */
#ifndef __MX6ULL_LANJUT_CONFIG_H
#define __MX6ULL_LANJUT_CONFIG_H
#include <asm/arch/imx-regs.h>
#include <linux/sizes.h>
#include "mx6_common.h"
#include <asm/mach-imx/gpio.h>
#include "imx_env.h"
#define is_mx6ull_9x9_evk()	CONFIG_IS_ENABLED(TARGET_MX6ULL_9X9_EVK)
#ifdef CONFIG_TARGET_MX6ULL_9X9_EVK
#define PHYS_SDRAM_SIZE		SZ_256M
#define BOOTARGS_CMA_SIZE   "cma=96M "
#else
#define PHYS_SDRAM_SIZE		SZ_512M
#define BOOTARGS_CMA_SIZE   ""
/* DCDC used on 14x14 EVK, no PMIC */
#undef CONFIG_LDO_BYPASS_CHECK
#endif
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN		(16 * SZ_1M)
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE		UART1_BASE
/* MMC Configs */
#ifdef CONFIG_FSL_USDHC
#define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC2_BASE_ADDR
/* NAND pin conflicts with usdhc2 */
#ifdef CONFIG_NAND_MXS
#define CONFIG_SYS_FSL_USDHC_NUM	1
#else
#define CONFIG_SYS_FSL_USDHC_NUM	2
#endif
#endif
/* I2C configs */
#ifdef CONFIG_CMD_I2C
#define CONFIG_SYS_I2C_MXC
#define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
#define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
#define CONFIG_SYS_I2C_SPEED		100000
#endif
#define CONFIG_SYS_MMC_IMG_LOAD_PART	1
#ifdef CONFIG_NAND_BOOT
#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(nandboot),16m(nandkernel),16m(nanddtb),16m(nandtee),-(nandrootfs)"
#else
#define MFG_NAND_PARTITION ""
#endif
#define CONFIG_CMD_READ
#define CONFIG_SERIAL_TAG
#define CONFIG_FASTBOOT_USB_DEV 0
#define CONFIG_MFG_ENV_SETTINGS \
	CONFIG_MFG_ENV_SETTINGS_DEFAULT \
	"initrd_addr=0x86800000\0" \
	"initrd_high=0xffffffff\0" \
	"emmc_dev=1\0"\
	"emmc_ack=1\0"\
	"sd_dev=1\0" \
	"mtdparts=" MFG_NAND_PARTITION \
	"\0"\
#if defined(CONFIG_NAND_BOOT)
#define CONFIG_EXTRA_ENV_SETTINGS \
	CONFIG_MFG_ENV_SETTINGS \
	TEE_ENV \
	"splashimage=0x8c000000\0" \
	"fdt_addr=0x83000000\0" \
	"fdt_high=0xffffffff\0"	  \
	"tee_addr=0x84000000\0" \
	"console=ttymxc0\0" \
	"bootargs=console=ttymxc0,115200 ubi.mtd=nandrootfs "  \
		"root=ubi0:rootfs rootfstype=ubifs "		     \
		BOOTARGS_CMA_SIZE \
		MFG_NAND_PARTITION \
		"\0" \
	"bootcmd=nand read ${loadaddr} 0x4000000 0xc00000;"\
		"nand read ${fdt_addr} 0x5000000 0x100000;"\
		"if test ${tee} = yes; then " \
			"nand read ${tee_addr} 0x6000000 0x400000;"\
			"bootm ${tee_addr} - ${fdt_addr};" \
		"else " \
			"bootz ${loadaddr} - ${fdt_addr};" \
		"fi\0"
#else
#define CONFIG_EXTRA_ENV_SETTINGS \
	CONFIG_MFG_ENV_SETTINGS \
	TEE_ENV \
	"script=boot.scr\0" \
	"image=zImage\0" \
	"console=ttymxc0\0" \
	"fdt_high=0xffffffff\0" \
	"initrd_high=0xffffffff\0" \
	"fdt_file=undefined\0" \
	"fdt_addr=0x83000000\0" \
	"tee_addr=0x84000000\0" \
	"tee_file=undefined\0" \
	"boot_fdt=try\0" \
	"ip_dyn=no\0" \
	"splashimage=0x8c000000\0" \
	"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
	"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
	"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
	"mmcautodetect=yes\0" \
	"mmcargs=setenv bootargs console=${console},${baudrate} " \
		BOOTARGS_CMA_SIZE \
		"root=${mmcroot}\0" \
	"loadbootscript=" \
		"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
	"bootscript=echo Running bootscript from mmc ...; " \
		"source\0" \
	"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
	"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
	"loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}\0" \
	"mmcboot=echo Booting from mmc ...; " \
		"run mmcargs; " \
		"if test ${tee} = yes; then " \
			"run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; " \
		"else " \
			"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
				"if run loadfdt; then " \
					"bootz ${loadaddr} - ${fdt_addr}; " \
				"else " \
					"if test ${boot_fdt} = try; then " \
						"bootz; " \
					"else " \
						"echo WARN: Cannot load the DT; " \
					"fi; " \
				"fi; " \
			"else " \
				"bootz; " \
			"fi; " \
		"fi;\0" \
	"netargs=setenv bootargs console=${console},${baudrate} " \
		BOOTARGS_CMA_SIZE \
		"root=/dev/nfs " \
		"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
	"netboot=echo Booting from net ...; " \
		"${usb_net_cmd}; " \
		"run netargs; " \
		"if test ${ip_dyn} = yes; then " \
			"setenv get_cmd dhcp; " \
		"else " \
			"setenv get_cmd tftp; " \
		"fi; " \
		"${get_cmd} ${image}; " \
		"if test ${tee} = yes; then " \
			"${get_cmd} ${tee_addr} ${tee_file}; " \
			"${get_cmd} ${fdt_addr} ${fdt_file}; " \
			"bootm ${tee_addr} - ${fdt_addr}; " \
		"else " \
			"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
				"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
					"bootz ${loadaddr} - ${fdt_addr}; " \
				"else " \
					"if test ${boot_fdt} = try; then " \
						"bootz; " \
					"else " \
						"echo WARN: Cannot load the DT; " \
					"fi; " \
				"fi; " \
			"else " \
				"bootz; " \
			"fi; " \
		"fi;\0" \
		"findfdt="\
			"if test $fdt_file = undefined; then " \
				"if test $board_name = ULZ-EVK && test $board_rev = 14X14; then " \
					"setenv fdt_file imx6ulz-14x14-evk.dtb; fi; " \
				"if test $board_name = EVK && test $board_rev = 9X9; then " \
					"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
				"if test $board_name = EVK && test $board_rev = 14X14; then " \
					"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
				"if test $board_name = LANJUT && test $board_rev = 14X14; then " \
					"setenv fdt_file imx6ull-14x14-lanjut.dtb; fi; " \
				"if test $fdt_file = undefined; then " \
					"echo WARNING: Could not determine dtb to use; " \
				"fi; " \
			"fi;\0" \
		"findtee="\
			"if test $tee_file = undefined; then " \
				"if test $board_name = ULZ-EVK && test $board_rev = 14X14; then " \
					"setenv tee_file uTee-6ulzevk; fi; " \
				"if test $board_name = EVK && test $board_rev = 9X9; then " \
					"setenv tee_file uTee-6ullevk; fi; " \
				"if test $board_name = EVK && test $board_rev = 14X14; then " \
					"setenv tee_file uTee-6ullevk; fi; " \
				"if test $board_name = LANJUT && test $board_rev = 14X14; then " \
					"setenv tee_file uTee-6ull_lanjut; fi; " \
				"if test $tee_file = undefined; then " \
					"echo WARNING: Could not determine tee to use; " \
				"fi; " \
			"fi;\0" \
#define CONFIG_BOOTCOMMAND \
	   "run findfdt;" \
	   "run findtee;" \
	   "mmc dev ${mmcdev};" \
	   "mmc dev ${mmcdev}; if mmc rescan; then " \
		   "if run loadbootscript; then " \
			   "run bootscript; " \
		   "else " \
			   "if run loadimage; then " \
				   "run mmcboot; " \
			   "else run netboot; " \
			   "fi; " \
		   "fi; " \
	   "else run netboot; fi"
#endif
/* Miscellaneous configurable options */
#define CONFIG_SYS_MEMTEST_START	0x80000000
#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x8000000)
#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
#define CONFIG_SYS_HZ			1000
/* Physical Memory Map */
#define PHYS_SDRAM			MMDC0_ARB_BASE_ADDR
#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM
#define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR
#define CONFIG_SYS_INIT_RAM_SIZE	IRAM_SIZE
#define CONFIG_SYS_INIT_SP_OFFSET \
	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_INIT_SP_ADDR \
	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
/* environment organization */
#define CONFIG_SYS_MMC_ENV_DEV		1	/* USDHC2 */
#define CONFIG_SYS_MMC_ENV_PART		0	/* user area */
#define CONFIG_MMCROOT			"/dev/mmcblk1p2"  /* USDHC2 */
#define CONFIG_IOMUX_LPSR
#ifdef CONFIG_FSL_QSPI
#define CONFIG_SYS_FSL_QSPI_AHB
#define FSL_QSPI_FLASH_NUM		1
#define FSL_QSPI_FLASH_SIZE		SZ_32M
#endif
/* NAND stuff */
#ifdef CONFIG_NAND_MXS
#define CONFIG_SYS_MAX_NAND_DEVICE	1
#define CONFIG_SYS_NAND_BASE		0x40000000
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_ONFI_DETECTION
#define CONFIG_SYS_NAND_USE_FLASH_BBT
/* DMA stuff, needed for GPMI/MXS NAND support */
#endif
#if defined(CONFIG_ENV_IS_IN_SPI_FLASH)
#define CONFIG_ENV_SPI_BUS		CONFIG_SF_DEFAULT_BUS
#define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
#define CONFIG_ENV_SPI_MODE		CONFIG_SF_DEFAULT_MODE
#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
#endif
/* USB Configs */
#ifdef CONFIG_CMD_USB
#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
#define CONFIG_MXC_USB_PORTSC  (PORT_PTS_UTMI | PORT_PTS_PTW)
#define CONFIG_MXC_USB_FLAGS   0
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#endif
#define CONFIG_FEC_XCV_TYPE             RMII
#define CONFIG_ETHPRIME			"eth1"
#define CONFIG_IMX_THERMAL
#ifndef CONFIG_SPL_BUILD
#if defined(CONFIG_DM_VIDEO)
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LINK
#define CONFIG_VIDEO_LOGO
#define CONFIG_SPLASH_SCREEN
#define CONFIG_SPLASH_SCREEN_ALIGN
#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#endif
#endif
#define CONFIG_MODULE_FUSE
#define CONFIG_OF_SYSTEM_SETUP
/* Network Configs */
#define CONFIG_IPADDR          192.168.137.234      /* board ip */
#define CONFIG_SERVERIP     192.168.137.1      /* server ip */
#define CONFIG_GATEWAYIP    192.168.137.1        /* board gateway ip */
#define CONFIG_NETMASK      255.255.255.0       /* board netmask */
#endif

以上添加了网络信息配置,因为在 mx6ull_14x14_lanjut_emmc_defconfig 中,我们有移除 DHCP 命令操作,因此如果使用到网络,那么必然需要配置静态网络 setenv ipaddr 这些,而在这里我们直接先配置好默认 ip(即 /* Network Configs */ 下的操作)。同样,在这里可以找到与 NAND、IIC、SPI、VIDEO 这些不需要的功能,部分通过 #ifdef 宏来启用,那么如果在 mx6ull_14x14_lanjut_emmc_defconfig 中有屏蔽相应的宏则不要处理,否则对于一些没有在 mx6ull_14x14_lanjut_emmc_defconfig 中出现的并且想要裁切的功能,可以直接屏蔽对应的宏(例如是对 board/freescale/mx6ull_lanjut/mx6ull_lanjut.c 中的操作选择)。

# 添加编译脚本

touch build.sh
vim build.sh

写入:

#!/bin/bash
# 若之前已经导入到环境变量则不需要
export PATH=$PATH:/usr/local/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin
# 若已经在顶层 Makefile 文件中指定则不需要
export ARCH=arm
# 若已经在顶层 Makefile 文件中指定则不需要
export CROSS_COMPILE=arm-none-linux-gnueabihf-
export LCPU=`grep -c processor /proc/cpuinfo`
make clean
make mx6ull_14x14_lanjut_emmc_defconfig
make -j${LCPU}

#

uboot 文件结构:

类型名称说明
文件夹api通用的 API 函数相关
arch与芯片架构相关
board板级相关信息
cmduboot 命令相关
common通用代码
configsuboot 配置内容
disk磁盘相关
doc各说明文档
drivers驱动代码相关
dts设备树相关
envuboot 环境相关
examples示例代码
fs文件系统相关
include头文件相关
liblib 库文件
Licenses许可证相关
net网络相关
post上电自检相关
scripts相关脚本
test测试代码
toolsuboot 构建工具相关
文件config.mk某个 Makefile 需要调用此文件
Kbuild用于生成汇编相关的文件
Kconfig图形配置界面相关文件
MAINTAINERS开发及维护记录
Makefile主 Makefile 脚本
README工程说明
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

夏沫の浅雨 微信支付

微信支付

夏沫の浅雨 支付宝

支付宝