文章目录
- [1 说明及源码获取](#1 说明及源码获取)
-
- [1.1 源码获取](#1.1 源码获取)
- [1.2 安装依赖包](#1.2 安装依赖包)
- [1.3 U-Boot源码打补丁](#1.3 U-Boot源码打补丁)
- [1.4 修改编译配置](#1.4 修改编译配置)
- [1.5 首次编译及创建默认配置文件](#1.5 首次编译及创建默认配置文件)
- [2 注意事项](#2 注意事项)
- [3 uboot移植](#3 uboot移植)
-
- [3.1 创建默认配置设备树](#3.1 创建默认配置设备树)
- [3.2 修改设备树Makefile配置项](#3.2 修改设备树Makefile配置项)
- [3.3 修改电源管理配置](#3.3 修改电源管理配置)
- [3.4 修改TF卡和EMMC配置](#3.4 修改TF卡和EMMC配置)
- [3.5 网络驱动修改](#3.5 网络驱动修改)
- [3.6 USB_OTG设备树修改](#3.6 USB_OTG设备树修改)
- [3.7 使能boot和bootd命令](#3.7 使能boot和bootd命令)
- [3.8 LCD驱动修改](#3.8 LCD驱动修改)
- [4 编译及烧录](#4 编译及烧录)
-
- [4.1 uboot编译](#4.1 uboot编译)
- [4.2 uboot烧录](#4.2 uboot烧录)
-
- [4.2.1 编译文件准备](#4.2.1 编译文件准备)
- [4.2.2 使用USB烧写uboot](#4.2.2 使用USB烧写uboot)
- [4.3 uboot运行](#4.3 uboot运行)
- [5 uboot移植结果验证](#5 uboot移植结果验证)
- [6 设置uboot下网络相关配置](#6 设置uboot下网络相关配置)
-
- [6.1 网络配置](#6.1 网络配置)
- [6.2 网络环境验证](#6.2 网络环境验证)
1 说明及源码获取
1.1 源码获取
使用正点原子提供的en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz。
使用如下命令解压文件:
bash
tar -xvf en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz
目录下包含了如下文件夹:
| 文件夹 | 描述 |
|---|---|
| linux-stm32mp-5.4.31-r0 | linux源码,版本号为5.4.31 |
| optee-os-stm32mp-3.9.0.r1-r0 | optee系统源码,版本为3.9.0 |
| tf-a-stm32mp-2.2.r1-r0 | tf-a源码,版本号为2.2 |
| tf-a-stm32mp-ssp-2.2.r1-r0 | tf-a源码,ssp全称为secure secert provisioning,安全相关的内容 |
| u-boot-stm32mp-2020.01-r0 | uboot源码,版本号为2020.01 |
U-Boot使用u-boot-stm32mp-2020.01-r0文件夹内容
1.2 安装依赖包
bash
sudo apt install libncurses5-dev bison flex
# 图形化配置界面需要库
sudo apt-get install build-essential
sudo apt-get install libncurses5-dev
1.3 U-Boot源码打补丁
将u-boot-stm32mp-2020.01-r0文件夹内容重新拷贝到一个新的文件夹中,例如/home/alientek/linux/da-mp1/da/uboot,在新的文件夹中使用如下命令打补丁:
bash
# 在/home/alientek/linux/da-mp1/da/uboot 文件夹下打开一个终端,执行如下命令:
tar -vxf u-boot-stm32mp-2020.01-r0.tar.gz
cd u-boot-stm32mp-2020.01/
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done # 打补丁
1.4 修改编译配置
主要修改Makefile文件:
- 添加
ARCH变量; - 添加
CROSS_COMPILE变量。
在u-boot-stm32mp-2020.01/Makefile中修改,在文件的第265行添加如下代码。
makefile
ARCH = arm
CROSS_COMPILE = arm-none-linux-gnueabihf-
添加前内容:

添加后内容:

1.5 首次编译及创建默认配置文件
使用如下命令进行uboot的首次编译:
bash
cd u-boot-stm32mp-2020.01/
make stm32mp15_trusted_defconfig
上述命令中make stm32mp15_trusted_defconfig,使用默认配置文件配置以下uboot,使用如下命令复制一个该文件,并重命名为stm32mp15_da_trusted_defconfig,作为编译时的配置文件
bash
cd u-boot-stm32mp-2020.01/
cd configs/
cp stm32mp15_trusted_defconfig stm32mp15_da_trusted_defconfig
make stm32mp15_da_trusted_defconfig
执行如下命令进行编译
bash
make DEVICE_TREE=stm32mp157d-ev1 all -j8
2 注意事项
uboot移植涉及修改内容较多,为避免最后结果不符合预期,建议可以在有效修改后分步骤编译运行,查看结果,可以提高最后结果的正确性。
3 uboot移植
uboot的移植并不是说完完全全的从零开始将uboot移植到现在所使用的开发板或者开发平台上。这样的移植方式基本是不可能的实现的,这个工作一般是半导体厂商做的,半导体厂商负责将uboot移植到他们的芯片上,因此半导体厂商都会自己做一个开发板,这个开发板就叫做原厂开发板,比如学习STM32的时候听说过的discover开发板就是ST自己做的。半导体厂商将uboot移植到自己的原厂开发板上,测试好以后就会将这个uboot发布出去,这就是大家常说的原厂BSP包。
一般做产品的时候就会参考原厂的开发板做硬件,然后在原厂提供的BSP包上做修改,将uboot或者linux kernel移植到硬件上。这就是uboot移植的一般流程:
- 在uboot中找到参考的开发平台,一般是原厂的开发板;
- 参考原厂开发板移植uboot到使用的开发板上。
正点原子STM32MP157开发板参考的是ST官方的STM32MP157EVK开发板做的硬件,因此在移植uboot的时候就可以将ST官方的STM32MP157EVK开发板为蓝本。
3.1 创建默认配置设备树
bash
cd u-boot-stm32mp-2020.01/
cd arch/arm/dts/
cp stm32mp157d-ed1.dts stm32mp157d-da.dts
cp stm32mp15xx-edx.dtsi stm32mp157d-da.dtsi
cp stm32mp157a-ed1-u-boot.dtsi stm32mp157d-da-u-boot.dtsi
打开stm32mp157d-da.dts文件,修改如下内容:
- 修改
#include "stm32mp15xx-edx.dtsi"头文件引用为#include "stm32mp157d-da.dtsi" - 修改
/节点下的compatible属性值为"st,stm32mp157d-da", "st,stm32mp157"。
如下所示:

3.2 修改设备树Makefile配置项
修改u-boot-stm32mp-2020.01/arch/arm/dts/Makefile文件,修改内容如下:
- 在
dtb-$(CONFIG_STM32MP15x)配置项中添加stm32mp157d-da.dtb。
修改后的内容为:
makefile
dtb-$(CONFIG_STM32MP15x) += \
stm32mp157a-avenger96.dtb \
stm32mp157a-dk1.dtb \
stm32mp157a-ed1.dtb \
stm32mp157a-ev1.dtb \
stm32mp157c-dk2.dtb \
stm32mp157c-ed1.dtb \
stm32mp157c-ev1.dtb \
stm32mp157d-dk1.dtb \
stm32mp157d-ed1.dtb \
stm32mp157d-ev1.dtb \
stm32mp157f-dk2.dtb \
stm32mp157f-ed1.dtb \
stm32mp157f-ev1.dtb \
stm32mp15xx-dhcom-pdk2.dtb \
stm32mp157d-da.dtb
3.3 修改电源管理配置
打开stm32mp157d-da-u-boot.dtsi文件,修改如下内容:
- 删除
/节点下config节点下的st,fastboot-gpios和st,stm32prog-gpios属性; - 删除
/节点下led节点下的red节点; - 删除
pmic节点。
修改前内容(文件部分内容,只涉及修改部分):
d
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright : STMicroelectronics 2018
*/
#include <dt-bindings/clock/stm32mp1-clksrc.h>
#include "stm32mp15-u-boot.dtsi"
#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
/ {
aliases {
i2c3 = &i2c4;
mmc0 = &sdmmc1;
mmc1 = &sdmmc2;
};
config {
u-boot,boot-led = "heartbeat";
u-boot,error-led = "error";
u-boot,mmc-env-partition = "ssbl";
st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
};
led {
red {
label = "error";
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
default-state = "off";
status = "okay";
};
};
};
#ifndef CONFIG_STM32MP1_TRUSTED
&clk_hse {
st,digbypass;
};
&i2c4 {
u-boot,dm-pre-reloc;
};
&i2c4_pins_a {
u-boot,dm-pre-reloc;
pins {
u-boot,dm-pre-reloc;
};
};
&pmic {
u-boot,dm-pre-reloc;
};
修改后内容(文件部分内容,只涉及修改部分);
d
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright : STMicroelectronics 2018
*/
#include <dt-bindings/clock/stm32mp1-clksrc.h>
#include "stm32mp15-u-boot.dtsi"
#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
/ {
aliases {
i2c3 = &i2c4;
mmc0 = &sdmmc1;
mmc1 = &sdmmc2;
};
config {
u-boot,boot-led = "heartbeat";
u-boot,error-led = "error";
u-boot,mmc-env-partition = "ssbl";
};
led {
};
};
#ifndef CONFIG_STM32MP1_TRUSTED
&clk_hse {
st,digbypass;
};
&i2c4 {
u-boot,dm-pre-reloc;
};
&i2c4_pins_a {
u-boot,dm-pre-reloc;
pins {
u-boot,dm-pre-reloc;
};
};
打开stm32mp157d-da.dtsi文件,修改如下内容:
- 删除
dac节点; - 删除
adc节点; - 删除
i2c4节点; - 删除
led节点; - 删除
sd_switch节点; - 在
/节点下添加电源信息节点,分别为vddcore、v3v3、vdd、vdd_usb、v1v8_audio。
需要添加的vddcore、v3v3、vdd、vdd_usb、v1v8_audio节点内容如下:
d
vddcore: regulator-vddcore {
compatible = "regulator-fixed";
regulator-name = "vddcore";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
v3v3: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "v3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v8_audio: regulator-v1v8-audio {
compatible = "regulator-fixed";
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
vdd: regulator-vdd {
compatible = "regulator-fixed";
regulator-name = "vdd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
vdd_usb: regulator-vdd-usb {
compatible = "regulator-fixed";
regulator-name = "vdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
内容较多,不再给出修改前后的文件内容,按照修改步骤修改即可。可下载资源,其中有一个uboot的压缩包,内容是本章移植的所有内容源码,含编译文件。
3.4 修改TF卡和EMMC配置
打开stm32mp157d-da.dtsi文件,修改如下内容:
- 修改
sdmmc1节点和sdmmc2节点。
修改前内容:
d
&sdmmc1 {
pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>;
pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>;
cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
disable-wp;
st,sig-dir;
st,neg-edge;
st,use-ckin;
bus-width = <4>;
vmmc-supply = <&vdd_sd>;
vqmmc-supply = <&sd_switch>;
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
sd-uhs-ddr50;
sd-uhs-sdr104;
status = "okay";
};
&sdmmc2 {
pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
non-removable;
no-sd;
no-sdio;
st,neg-edge;
bus-width = <8>;
vmmc-supply = <&v3v3>;
vqmmc-supply = <&vdd>;
mmc-ddr-3_3v;
status = "okay";
};
修改后内容:
d
&sdmmc1 {
pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdmmc1_b4_pins_a>;
pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
st,neg-edge;
broken-cd;
bus-width = <4>;
vmmc-supply = <&v3v3>;
status = "okay";
};
&sdmmc2 {
pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
non-removable;
st,neg-edge;
bus-width = <8>;
vmmc-supply = <&v3v3>;
keep-power-in-suspend;
status = "okay";
};
3.5 网络驱动修改
打开stm32mp157d-da.dtsi文件,修改如下内容:
- 添加
ethernet0节点。
ethernet0节点内容如下:
d
ðernet0 {
status = "okay";
pinctrl-0 = <ðernet0_rgmii_pins_a>;
pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;
pinctrl-names = "default", "sleep";
phy-mode = "rgmii-id";
max-speed = <1000>;
phy-handle = <&phy0>;
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy0: ethernet-phy@0 {
reg = <0>;
};
};
};
正点原子V1.3及以后版本的核心板开始将网络PHY芯片更换为了国产裕太电子的YT8511所以需要修改一下驱动。使用提供的资源目录/yt8511/phy.c替换掉u-boot-stm32mp-2020.01/drivers/net/phy/phy.c文件即可。
资源需要在此处下载。
3.6 USB_OTG设备树修改
打开stm32mp157d-da.dtsi文件,修改如下内容:
- 在
/节点下,添加usb_phy_tuning节点; - 添加
i2c1节点及在i2c1节点下添加stusb1600节点; - 修改
usbotg_hs节点; - 添加
usbh_ehci节点; - 添加
usbphyc节点。
usb_phy_tuning节点内容如下:
d
usb_phy_tuning: usb-phy-tuning {
st,hs-dc-level = <2>;
st,fs-rftime-tuning;
st,hs-rftime-reduction;
st,hs-current-trim = <15>;
st,hs-impedance-trim = <1>;
st,squelch-level = <3>;
st,hs-rx-offset = <2>;
st,no-lsfs-sc;
};
i2c1节点内容如下:
d
&i2c1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c1_pins_b>;
pinctrl-1 = <&i2c1_pins_sleep_b>;
i2c-scl-rising-time-ns = <100>;
i2c-scl-falling-time-ns = <7>;
status = "okay";
/delete-property/dmas;
/delete-property/dma-names;
stusb1600@28 {
compatible = "st,stusb1600";
reg = <0x28>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpiog>;
pinctrl-names = "default";
pinctrl-0 = <&stusb1600_pins_a>;
status = "okay";
vdd-supply = <&vin>;
connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
power-opmode = "default";
port {
con_usbotg_hs_ep: endpoint {
remote-endpoint = <&usbotg_hs_ep>;
};
};
};
};
};
usbotg_hs修改后节点内容如下:
d
&usbotg_hs {
phys = <&usbphyc_port1 0>;
phy-names = "usb2-phy";
usb-role-switch;
status = "okay";
port {
usbotg_hs_ep: endpoint {
remote-endpoint = <&con_usbotg_hs_ep>;
};
};
};
usbh_ehci节点内容如下:
d
&usbh_ehci {
phys = <&usbphyc_port0>;
status = "okay";
};
usbphyc节点内容如下:
d
&usbphyc {
status = "okay";
};
打开stm32mp157d-da-u-boot.dtsi文件,修改如下内容:
- 添加
usbotg_hs节点。
usbotg_hs节点内容如下:
d
&usbotg_hs {
u-boot,force-b-session-valid;
hnp-srp-disable;
/* TEMP: force peripheral for USB OTG */
dr_mode = "peripheral";
};
3.7 使能boot和bootd命令
ST官方uboot默认没有使能boot和bootd这两个命令,命令实现源文件为cmd/bootm.c,内容如下:
d
/*******************************************************************/
/* bootd - boot default image */
/*******************************************************************/
#if defined(CONFIG_CMD_BOOTD)
int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
return run_command(env_get("bootcmd"), flag);
}
U_BOOT_CMD(
boot, 1, 1, do_bootd,
"boot default, i.e., run 'bootcmd'",
""
);
/* keep old command name "bootd" for backward compatibility */
U_BOOT_CMD(
bootd, 1, 1, do_bootd,
"boot default, i.e., run 'bootcmd'",
""
);
#endif
分析文件,boot和bootd命令由CONFIG_CMD_BOOTD宏定义决定是否编译进uboot中,在include/configs/stm32mp1.h中添加CONFIG_CMD_BOOTD宏定义。
如下所示:

3.8 LCD驱动修改
打开stm32mp157d-da.dts文件,修改如下内容:
- 在
/节点下添加panel_backlight节点; - 在
/节点下添加panel_rgb节点; - 添加
ltdc节点。
panel_backlight节点内容如下:
d
panel_backlight: panel-backlight {
compatible = "gpio-backlight";
gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
default-on;
status = "okay";
};
panel_rgb节点内容如下:
d
panel_rgb: panel-rgb {
compatible = "simple-panel";
pinctrl-names = "default", "sleep";
pinctrl-0 = <<dc_pins_b>;
pinctrl-1 = <<dc_pins_sleep_b>;
backlight = <&panel_backlight>;
status = "okay";
port {
panel_in_rgb: endpoint {
remote-endpoint = <<dc_ep0_out>;
};
};
display-timings {
native-mode = <&timing0>; /* 时序信息 */
timing0: timing0 {
clock-frequency = <51200000>; /* LCD 像素时钟,单位 Hz */
hactive = <1024>; /* LCD X 轴像素个数 */
vactive = <600>; /* LCD Y 轴像素个数 */
hfront-porch = <160>; /* LCD hfp 参数 */
hback-porch = <140>; /* LCD hbp 参数 */
hsync-len = <20>; /* LCD hspw 参数 */
vback-porch = <20>; /* LCD vbp 参数 */
vfront-porch = <12>; /* LCD vfp 参数 */
vsync-len = <3>; /* LCD vspw 参数 */
};
};
};
ltdc节点内容如下:
d
<dc {
status = "okay";
pinctrl-names = "default";
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_rgb>;
};
};
};
4 编译及烧录
4.1 uboot编译
使用如下命令编译:
bash
cd u-boot-stm32mp-2020.01/
make DEVICE_TREE=stm32mp157d-da all -j8
# 结束后会在 u-boot-stm32mp-2020.01 源码目录中生成 u-boot.stm32 文件,这个文件就是需要烧录的文件。
将编译产生的u-boot.stm32文件传输到win系统中,便于后续烧录
4.2 uboot烧录
4.2.1 编译文件准备
将编译生成的u-boot.stm32、tf-a-stm32mp157d-da-trusted.stm32和tf-a-stm32mp157d-da-serialboot.stm32文件(其中tf-a-stm32mp157d-da-trusted.stm32和tf-a-stm32mp157d-da-serialboot.stm32使用已经编译好的),统一放入文件夹中,例如:da-images文件夹。在da-images文件夹中添加da.tsv文件;文件内容如下所示:
tex
#Opt Id Name Type Device Offset Binary
- 0x01 fsbl1-boot Binary none 0x0 tf-a-stm32mp157d-da-serialboot.stm32
- 0x03 ssbl-boot Binary none 0x0 u-boot.stm32
P 0x04 fsbl1 Binary mmc1 boot1 tf-a-stm32mp157d-da-trusted.stm32
P 0x05 fsbl2 Binary mmc1 boot2 tf-a-stm32mp157d-da-trusted.stm32
P 0x06 ssbl Binary mmc1 0x00080000 u-boot.stm32
文件内容格式要严格遵循下图:

tsv语法要求只能用TAB键,不能用空格!以#开头为注释。
最终da-images文件夹中的内容如下:

使用STM32CubeProgrammer采用USB的方式烧写至开发板中,也就是USB_OTG口来烧写系统。
4.2.2 使用USB烧写uboot
通过USBType-C线将开发板的USB_OTG和USB_TTL连接到电脑上。

设置开发板拨码开关,设置为000,也就是从USB启动,然后复位开发板。
打开STM32CubeProgrammer,选择USB连接方式,Port选择USB1。

USB设置好以后点击右上角的"Connect"来连接开发板,连接成功以后左下角的log区域就会输出一些信息,右侧中间的数据区域也会显示开发板默认的分区情况,右下角会显示目标板信息,如图所示:

STM32CubeProgrammer要使用FlashLayout文件来烧写系统,也就是da-images文件夹下的da.tsv。点击界面上的"Open File",打开da.tsv,如下图所示:

烧写完成后会有如下提示:

4.3 uboot运行
打开MobaXterm软件,设置好与开发板连接的串口,波特率选择115200。
设置开发板拨码开关为010,也就是从EMMC启动,然后复位开发板!
在串口中观察启动过程。
5 uboot移植结果验证

6 设置uboot下网络相关配置
6.1 网络配置
bash
setenv ipaddr 192.168.10.102
setenv ethaddr b8:ae:1d:01:01:00
setenv getwayip 192.168.10.1
setenv netmask 255.255.255.0
setenv serverip 192.168.10.101
saveenv
6.2 网络环境验证
网络拓扑结构为:
- 路由器连接家庭网络,可上外网;
- 开发板和笔记本电脑使用网线连接到路由器上;
- 虚拟机在笔记本电脑上运行。
目前各个终端IP地址如下:
- 开发板:192.168.10.102;
- 虚拟机:192.168.10.101;
- 笔记本电脑:192.168.10.100。
