imx-6ULL uboot 移植

写在前面:

本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。

目录

首发及后期更新将于 https://arachnid.cc/6ull-uboot-transplant 上,此处仅作二次备份。

开发平台: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

解压添加至本地:

bash 复制代码
# 创建存放编译工具链的文件夹
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 

添加环境变量:

bash 复制代码
# 添加到系统环境变量(对所有用户有效)
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

# 以上二选一

测试命令:

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

uboot 源码

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

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

bash 复制代码
# 拉取源码文件
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 关键字的区分,以下摘录解释:

text 复制代码
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。

编译验证

bash 复制代码
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 工具:

bash 复制代码
sudo apt install make

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

bash 复制代码
sudo apt install gcc

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

bash 复制代码
# 语法分析工具
sudo apt install bison
# 词法分析工具
sudo apt install flex

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

移植

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

开发板文件夹

bash 复制代码
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 文件:

bash 复制代码
vim board/freescale/mx6ull_lanjut/Kconfig

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

text 复制代码
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 文件:

bash 复制代码
vim board/freescale/mx6ull_lanjut/Makefile

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

3、imximage_lpddr2.cfgimximage.cfg 文件:

bash 复制代码
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 文件:

bash 复制代码
vim board/freescale/mx6ull_lanjut/MAINTAINERS

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

text 复制代码
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 文件:

bash 复制代码
vim board/freescale/mx6ull_lanjut/mx6ull_lanjut.c
  • board_late_init 函数

    c 复制代码
    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 函数

    c 复制代码
    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 文件:

bash 复制代码
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 文件:

bash 复制代码
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"

同时更改以下内容:

text 复制代码
/ {
	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 包含文件,分别添加文件。

bash 复制代码
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 文件:

bash 复制代码
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 文件:

bash 复制代码
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 来指定传递给内核的设备树文件名)

    text 复制代码
    		"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 设备树文件名)

    text 复制代码
    		"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 文件:

bash 复制代码
vim arch/arm/dts/Makefile

修改:

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 文件:

bash 复制代码
vim arch/arm/mach-imx/mx6/Kconfig

修改:

config TARGET_MX6ULL_14X14_EVK 配置的下方添加:

text 复制代码
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" 配置的下方添加:

text 复制代码
source "board/freescale/mx6ull_lanjut/Kconfig"

定制外设

移除 74lv595 芯片相关配置

1、mx6ull_14x14_lanjut_emmc_defconfig 文件:

bash 复制代码
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 文件:

bash 复制代码
vim arch/arm/dts/imx6ul-14x14-lanjut.dtsi

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

text 复制代码
/ {
	// 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、功能配置修改

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

text 复制代码
...

&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 芯片复位的控制:

text 复制代码
&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,因此不需要修改:

text 复制代码
&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、配置分析

text 复制代码
...

&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 等功能。

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

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

c 复制代码
#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 个值可以在该头文件顶部看到说明:

c 复制代码
/*
 * 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_ofs conf_reg_ofs input_reg_ofs mux_mode input_val config_val
0x0078 0x0304 0x0000 1 0 0x1b0b0

B、追加配置

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

text 复制代码
...

&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 对不需要的功能进行屏蔽操作:

text 复制代码
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 环境及启动初始化。

c 复制代码
/* 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 中的操作选择)。

添加编译脚本

bash 复制代码
touch build.sh
vim build.sh

写入:

bash 复制代码
#!/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 板级相关信息
^^ cmd uboot 命令相关
^^ common 通用代码
^^ configs uboot 配置内容
^^ disk 磁盘相关
^^ doc 各说明文档
^^ drivers 驱动代码相关
^^ dts 设备树相关
^^ env uboot 环境相关
^^ examples 示例代码
^^ fs 文件系统相关
^^ include 头文件相关
^^ lib lib 库文件
^^ Licenses 许可证相关
^^ net 网络相关
^^ post 上电自检相关
^^ scripts 相关脚本
^^ test 测试代码
^^ tools uboot 构建工具相关
文件 config.mk 某个 Makefile 需要调用此文件
^^ Kbuild 用于生成汇编相关的文件
^^ Kconfig 图形配置界面相关文件
^^ MAINTAINERS 开发及维护记录
^^ Makefile 主 Makefile 脚本
^^ README 工程说明
相关推荐
有来技术9 分钟前
Linux 服务器安装 Docker - CentOS 9 (Stream)
linux·服务器·docker
jekc86835 分钟前
Centos 相关网络配置
linux·网络·centos
DADIAN_GONG36 分钟前
How to install tree on Centos? what is difference between apt and yum?
linux·运维·centos
C++忠实粉丝3 小时前
计算机网络之应用层协议HTTP
linux·网络·c++·网络协议·tcp/ip·计算机网络·http
Lin_Aries_04213 小时前
CentOS 7 安装部署 KVM
linux·运维·centos
深思慎考3 小时前
计算机操作系统——进程控制(Linux)
linux·服务器·c++·c
阿熊不会编程4 小时前
【计网】自定义协议与序列化(一) —— Socket封装于服务器端改写
linux·开发语言·网络·c++·设计模式
北冥有鱼被烹4 小时前
微知-如何通过lspci指定某个deviceid查看pcie设备?(lspci -d 15b3:和lspci -d :1021 )
linux·pcie
炽天使4 小时前
aws rds-mysql不支持性能详情监控
linux·数据库·mysql·云计算·aws·rds