目录
U-Boot(Universal Boot Loader)是一个开源的引导加载程序,广泛应用于嵌入式系统中。U-Boot 提供了硬件初始化、内核加载、设备驱动支持等功能,并为操作系统(如 Linux)提供启动环境。U-Boot 的移植涉及将其从现有平台迁移到新的硬件平台。这个过程包括配置 U-Boot 以支持新的硬件、编译、调试以及验证 U-Boot 是否能够成功启动操作系统。
1 说明
开发板:IMX6ULL EMMC版
半导体厂商会将 uboot 移植到他们自己的原厂开发板上,测试好以后就会将这个 uboot 发布出去,这就是大家常说的原厂 BSP 包。我们一般做产品的时候就会参考原厂的开发板做硬件,然后在原厂提供的 BSP 包上做修改,将 uboot 或者 linux kernel 移植到我们的硬件上。
2 NXP官方U-BOOT下载
NXP官方维护的uboot的网址为:linkhttps://github.com/nxp-imx/uboot-imx。
在Liunx中创建目录(mkdir NXP-uboot),然后使用git命令下载uboot源码。
git clone https://github.com/nxp-imx/uboot-imx.git
3 配置U-BOOT
通过vscode链接linux,打开下载好的uboot源码。
3.1 configs目录
在这个目录下面有很多的*defconfig文件,我们现在要做的就是找到适合我们开发板的defconfig文件。我们使用到的开发板是IMX6ULL EMMC版,因此选择:
mx6ull_14x14_evk_emmc_defconfig
3.2 初步编译
找到这个配置文件之后,初步编译这个文件,使用如下的命令:
step 1
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
执行完之后可能会报错,说缺少相关的包,只需要安装即可。
step 2
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
编译完之后会生成相应的文件。
3.3烧写测试
这里具体的烧写测试省略,本文主要着重介绍一下如何移植一个uboot。
4 U-BOOT移植
首先这里说明一下,后文会大概说明如何从将一个新的uboot移植到自己的板子上,这里选择的uboot主要是参考NXP官方移植好的uboot进行移植
4.1 下载nxp的uboot源码
下载源码。
上文提到了编译uboot的命令,可以发现:
step 1
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
执行完之后可能会报错,说缺少相关的包,只需要安装即可。
step 2
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
这里涉及到一个文件mx6ull_14x14_evk_emmc_defconfig,那这个文件是干什么的,如果我要为一个新的板子移植uboot是不是要新建这么一个文件,答案肯定是必须的。那这个文件是干什么的?
针对不同的开发板,U-Boot 会在 config 目录中提供不同的 defconfig 文件。
如果到这里你还是不理解,那么没关系,继续往下看。
4.2 是否存在一种借助参考平台移植UBOOT的范式?
注意:本小节的只是为了参考一款芯片uboot的代码,移植到自己的开发板,这里并不是移植一个全新的uboot。而是在芯片厂商提供的参考的uboot的基础上,增加一个属于自己板子的uboot。
1、配置目标主板的默认参数(defconfig)。
2、在(Kconfig)中注册新目标板。
3、修改Makefile确保代码能被编译。
4、实现板级支持代码board/。
5、定义include/configs/头文件。
6、配置设备树DTS。
7、编译、烧录、调试
接下来本小节就围绕这几个方面来具体进行总结分析:
4.2.1 配置目标主板的默认参数(defconfig)
在configs目录下面构建自己板子的defconfig文件:
这里的mx6ull_14x14_evk_emmc_defconfig这个文件时nxp维护的uboot自带的文件,mx6ull_pengfei_emmc_defconfig为自己板子的文件,这里名字可以自己根据自己的实际情况命名。
然后修改mx6ull_pengfei_emmc_defconfig这个文件:
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullevk/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_14X14_EVK=y
CONFIG_CMD_GPIO=y
----------------上面是未修改的文件--------下面是修改之后的文件----------------------------
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_pengfei_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_PENGFEI_EMMC=y
CONFIG_CMD_GPIO=y
4.2.2 在(Kconfig)中注册新目标板
这部分的内容在4.2.4中有具体实现。
4.2.3 修改Makefile确保代码能被编译
这部分的内容在4.2.4中有具体实现。
4.2.4 实现板级支持代码board/
板级的支持文件一般在board/目录下面,我们还是根据nxp为 I.MX6ULL EVK开发板涉及的板级文件夹进行修改。进入board目录之后,将mx6ullevk文件夹复制并命名为自己的文件夹。
cp mx6ullevk/ mx6ull_pengfei_emmc -rf
复制完成之后,进入这个文件夹,可以发现:
(1)将文件夹下面的mx6ullevk.c文件重命名为mx6ull_pengfei_emmc.c。
(2)修改文件夹下的makefile,使mx6ull_pengfei_emmc.c能够正常编译。
# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := mx6ullevk.o
extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@
----------------------------修改后-----------------------------------------
# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := mx6ull_pengfei_emmc.o
extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@
(3)修改文件夹下的imximage.cfg。
PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000
//修改为:
PLUGIN board/freescale/mx6ull_pengfei_emmc/plugin.bin 0x00907000
(4)修改文件夹下的Kconfig。
if TARGET_MX6ULL_14X14_EVK || TARGET_MX6ULL_9X9_EVK
config SYS_BOARD
default "mx6ullevk"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "mx6ullevk"
endif
//修改为
if TARGET_MX6ULL_PENGFEI_EMMC
config SYS_BOARD
default "mx6ull_pengfei_emmc"
config SYS_VENDOR
default "freescale"
config SYS_SOC
default "mx6"
config SYS_CONFIG_NAME
default "mx6ull_pengfei_emmc"
endif
(5)修改文件夹下的MAINTAINERS。
MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ullevk/
F: include/configs/mx6ullevk.h
F: configs/mx6ull_14x14_evk_defconfig
F: configs/mx6ull_9x9_evk_defconfig
//修改为:
MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ull_pengfei_emmc/
F: include/configs/mx6ull_pengfei_emmc.h
(6)修改arch/arm/cpu/armv7/mx6/Kconfig。
这里再顶层的Kconfig中要进行一些修改,前面的板级文件夹中的Kconfig,具体修改如下:
//在arch/arm/cpu/armv7/mx6/Kconfig找个位置,加入下面的内容
config TARGET_MX6ULL_PENGFEI_EMMC
bool "Support mx6ull_pengfei_emmc"
select MX6ULL
select DM
select DM_THERMAL
//在arch/arm/cpu/armv7/mx6/Kconfig最后面,也就是#endif之前增加一行下面的内容
source "board/freescale/mx6ull_pengfei_emmc/Kconfig"
4.2.5 定义include/configs/头文件
在这个文件夹地下有很多板级的头文件,同样我们找到nxp定义的头文件,然后复制为自己板子的头文件,具体操作如下:
打开这个文件发现,这个文件都是进行判断一些宏,然后进行宏的定义以及宏的注释,这就和我们在阅读uboot源码的时候对应上了,这个文件的具体作用是裁剪uboot的相关功能,如果需要开启某个功能就打开这个宏,如果不需要就删除或者注释相关的宏。
同样的套路,去这个头文件中进行修改(在这个文件的14行包含了一个头文件mx6_common.h),如果发现当前头文件并没有开启某个功能但是实际却开启了,可以去mx6_common.h这个头文件进行查找。
这个有文件基本不需要改动,如果不涉及功能的选择,那只需要修改一个地方,那就是8、9行:
#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H
//将其修改为:
#ifndef __MX6ULL_PENGFEI_EMMC_CONFIG_H
#define __MX6ULL_PENGFEI_EMMC_CONFIG_H
至此,就可以进行编译测试,编译通过之后,通过:
grep -nR "mx6ull_pengfei_emmc.h"
查看是否有很多的文件引用了这个头文件,如果引用了,那就说明uboot移植成功。