RK3588设备H88K适配主线U-Boot

 

获取编译源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
sudo apt install bison flex gcc-arm-linux-gnueabi u-boot-tools

# 也可选用ARM官方源:https://github.com/ARM-software/arm-trusted-firmware
git clone --depth 1 https://github.com/TrustedFirmware-A/trusted-firmware-a
cd trusted-firmware-a
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3588 bl31
# Built /home/leux/uboot/trusted-firmware-a/build/rk3588/release/bl31/bl31.elf successfully

# 既可使用上面开源的TrustedFirmware-A自行编译,也可使用下面Rockchip提供的闭源BL31成品
# wget https://github.com/rockchip-linux/rkbin/raw/master/bin/rk35/rk3588_bl31_v1.48.elf
# 如下Rockchip TPL是用来对 DRAM 初始化提供支持的,它位于 rkbin 库中没有开源,需要传递给 U-boot
wget https://github.com/rockchip-linux/rkbin/raw/master/bin/rk35/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.18.bin


# 获取并解压U-Boot源码
wget https://ftp.denx.de/pub/u-boot/u-boot-2025.01.tar.bz2
tar -xjvf u-boot-2025.01.tar.bz2 && cd u-boot-2025.01
# 等后续适配完成再使用这下面的命令编译即可,可选闭源BL31成品:export BL31=../rk3588_bl31_v1.48.elf
export BL31=../trusted-firmware-a/build/rk3588/release/bl31/bl31.elf
export ROCKCHIP_TPL=../rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.18.bin
make h88k-rk3588_defconfig
make CROSS_COMPILE=aarch64-linux-gnu-


# 编译完成后可刷入编译好的U-Boot文件,在源码根目录下的 u-boot-rockchip.bin 文件
# 当 seek=64 时,由于默认块大小是 512 字节所以会跳过 64*512=32768 字节,也就是 32KB 的空间
sudo dd if=u-boot-rockchip.bin of=/dev/mmcblk1 seek=64 conv=notrunc

初步适配设备

  1. 准备适配设备的DTS到指定路径,这里下载使用别人写好的到指定路径

wget https://github.com/DHDAXCW/lede-rockchip/raw/stable/package/boot/uboot-rockchip/src/arch/arm/dts/rk3588-h88k.dts -O dts/upstream/src/arm64/rockchip/rk3588-hinlink-h88k.dts

  1. 拷贝 Armsom-Sige7 的相关 u-boot.dtsi 配置,这个dtsi仅含有 #include "rk3588-u-boot.dtsi" 所以无需修改

cp arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi arch/arm/dts/rk3588-h88k-u-boot.dtsi

  1. 继续拷贝 Armsom-Sige7 的配置文件并将相关修改为适配设备的,这里的设备树命名要与上面下载的命名保持一致

cp configs/sige7-rk3588_defconfig configs/h88k-rk3588_defconfig

1
2
3
CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588-hinlink-h88k"
CONFIG_TARGET_H88K_RK3588=y
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-hinlink-h88k.dtb"
  1. 在RK3588架构里添加适配设备,添加后需重新 make h88k-rk3588_defconfig 才能生效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 根据如下补丁在 arch/arm/mach-rockchip/rk3588/Kconfig 中修改添加
--- a/arch/arm/mach-rockchip/rk3588/Kconfig
+++ b/arch/arm/mach-rockchip/rk3588/Kconfig
@@ -285,6 +285,30 @@
USB PD over USB Type-C
Size: 92mm x 62mm

+config TARGET_H88K_RK3588
+ bool "HINLINK H88K RK3588 board"
+ select BOARD_LATE_INIT
+ help
+ HINLINK H88K is a Rockchip RK3588 based SBC (Single Board Computer)
+ by HINLINK.
+
+ There are two variants depending on the DRAM size : 8G and 16G.
+
+ Specification:
+
+ Rockchip Rk3588 SoC
+ 4x ARM Cortex-A76, 4x ARM Cortex-A55
+ 8/16GB memory LPDDR4
+ Mali G610MC4 GPU
+ 2x MIPI CSI 2 multiple lanes connector
+ 32GB/64GB on board eMMC
+ 1x MicroSD Card slot, 2x SIM Card slot
+ 1x USB 2.0 Type-A, 3x USB 3.0 Type-A, 1x USB 3.0 Type-C
+ 1x HDMI 2.1 output, 1x HDMI 2.0 output, 1x HDMI 2.0 input
+ 2x RTL8125B 2.5 Gbps Ethernet port, 1x RTL8211F 1 Gbps Ethernet port
+ USB PD over USB Type-C
+ Size: 155mm x 105mm x 40mm
+
config TARGET_QUARTZPRO64_RK3588
bool "Pine64 QuartzPro64 RK3588 board"
select BOARD_LATE_INIT
@@ -385,6 +409,7 @@
default 0x00a00000

source "board/armsom/sige7-rk3588/Kconfig"
+source "board/hinlink/h88k-rk3588/Kconfig"
source "board/coolpi/genbook_cm5_rk3588/Kconfig"
source "board/edgeble/neural-compute-module-6/Kconfig"
source "board/friendlyelec/cm3588-nas-rk3588/Kconfig"
  1. 继续创建上面指定的 board/hinlink/h88k-rk3588/Kconfig 文件,继续拷贝 Armsom-Sige7 的相关配置并修改

cp board/armsom/sige7-rk3588/Kconfig board/hinlink/h88k-rk3588/Kconfig

1
2
3
4
5
6
7
8
9
10
11
12
if TARGET_H88K_RK3588

config SYS_BOARD
default "h88k-rk3588"

config SYS_VENDOR
default "hinlink"

config SYS_CONFIG_NAME
default "h88k-rk3588"

endif
  1. 根据上面 SYS_CONFIG_NAME 的值(即:h88k-rk3588.h),继续拷贝 Armsom-Sige7 的相关配置并修改

cp include/configs/sige7-rk3588.h include/configs/h88k-rk3588.h

1
2
3
4
5
6
7
8
9
10
#ifndef __H88K_RK3588_H
#define __H88K_RK3588_H

#define ROCKCHIP_DEVICE_SETTINGS \
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"

#include <configs/rk3588_common.h>

#endif /* __H88K_RK3588_H */

添加网卡支持

  1. 本适配设备拥有 1x RTL8211F 1G, 2x RTL8125B 2.5G 共三个网口,在上面设备初步适配完成后我们可以看到 Net: No ethernet found. ,那么怎样驱动网卡呢?

  2. RK3588自带原生双千兆网卡,但本设备只用了一个千兆。驱动采用 RTL8211F 的千兆以太网口 ETH0,如下操作完成即可显示 Net: eth0: ethernet@fe1b0000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 如下内容来自:https://github.com/armbian/linux-rockchip/blob/rk-6.1-rkr5.1/arch/arm64/boot/dts/rockchip/rk3588-hinlink-h88k.dts
# 首先在 dts/upstream/src/arm64/rockchip/rk3588-hinlink-h88k.dts 中添加网卡节点
&mdio0 {
rgmii_phy: phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x1>;
};
};

&gmac0 {
phy-mode = "rgmii-rxid";
clock_in_out = "output";

snps,reset-gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 20ms, 100ms for rtl8211f */
snps,reset-delays-us = <0 20000 100000>;

phy-handle = <&rgmii_phy>;
pinctrl-names = "default";
pinctrl-0 = <&gmac0_miim
&gmac0_tx_bus2
&gmac0_rx_bus2
&gmac0_rgmii_clk
&gmac0_rgmii_bus>;

tx_delay = <0x44>;
status = "okay";
};

# 然后在配置文件 configs/h88k-rk3588_defconfig 中添加如下配置即可
CONFIG_PHY_REALTEK=y
CONFIG_DWC_ETH_QOS=y
CONFIG_DWC_ETH_QOS_ROCKCHIP=y

=> mii dev # 查看GMAC网卡和相关信息
MII devices: 'ethernet@fe1b0000'
Current device: 'ethernet@fe1b0000'

=> setenv ethact ethernet@fe1b0000 # 可以通过设置 ethact 来管理和切换默认的网络通信接口
=> saveenv # 将当前活动的以太网设备设置为 ethernet@fe1b0000 并保存配置
=> printenv ethact # 查看当前活动的以太网设备
ethact=ethernet@fe1b0000

添加PCIE支持

  1. 查询开发板原厂GPIO配置表得知如下信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# ETH0 千兆以太网
⚫ V1版本的外壳CNC标识了ETH2,后期修改为ETH0
⚫ 以太网接口采用RTL8211F
⚫ GMAC数据线连接到【GMAC0】,IO电压是1.8V
⚫ GMAC0_RSTn连接到【AM25 GPIO4_B3】
⚫ GMAC0_MDC连接到【AB34 GPIO4_C4】
⚫ GMAC0_MDIO连接到【AB33 GPIO4_C5】
⚫ 其他GPIO暂时未写,请参考DTS,编译的时候合入

# ETH1 2.5G 以太网
⚫ ETH1以太网接口采用RTL8125B PCIE转2.5G网口
⚫ PCIE数据线和时钟线均连接到【PCIE30X1_1】
⚫ PCIE30X1_1_PERSTn_M1连接到【AM29 GPIO4_A2】
⚫ 其他GPIO暂时未写,请参考DTS,编译的时候合入

# ETH2 2.5G 以太网
⚫ V1版本的外壳CNC标识了ETH0,后期修改为ETH2
⚫ ETH2以太网接口采用RTL8125B PCIE转2.5G网口
⚫ PCIE数据线和时钟线均连接到【PCIE20_0】
⚫ RTL8125_PERSTn_M1连接到【AK27 GPIO4_A5】
⚫ 其他GPIO暂时未写,请参考DTS,编译的时候合入

# PCIE NVME 硬盘
⚫ PCIE NVME支持2280规格长度,使用4条Lane,连接到【PCIE30X4接口】最大速率发挥NVME的读写优势
⚫ NVME不需要控电,默认12V上电,NVME就能获电。PCIE的时钟由外置时钟发生器产生
⚫ PCIE30X4_PERSTn 连接到【AJ27 PCIE30X4_PERSTN_M1】,一定要配置 PCIE 功能,而不是GPIO
⚫ PCIE30X4_CLKREQN 连接到【AL26 PCIE30X4_CLKREQN_M1】,一定要配置 PCIE 功能,而不是GPIO
⚫ PCIE30X4_WAKEN 连接到【AJ26 PCIE30X4_WAKEN_M1】,一定要配置 PCIE 功能,而不是GPIO

# 另附RK3588的PCIe控制器在DTS中对应节点名称:
_________________________________________________________________________________________
节点 | 可用PHY | 当前接入设备 |
-----------------------------------------------------------------------------------------
pcie3x4 pcie@fe150000 | pcie30phy | Nvme 760P |
pcie3x2 pcie@fe160000 | pcie30phy | 未知 |
pcie2x1l0 pcie@fe170000 | pcie30phy,combphy1_ps | MTK7916 |
pcie2x1l1 pcie@fe180000 | pcie30phy,combphy2_psu | RTL8125 |
pcie2x1l2 pcie@fe190000 | pcie30phy,combphy0_ps | RTL8125 |
-----------------------------------------------------------------------------------------

# 如下DTS均借鉴自:https://github.com/armbian/linux-rockchip/blob/rk-6.1-rkr5.1/arch/arm64/boot/dts/rockchip/rk3588-hinlink-h88k.dts

  1. 添加采用 RTL8125B 的PCIE转2.5G网口 ETH1 ETH2 节点,如下操作完成可在U-Boot中找到PCIE网卡但不知道怎么用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 首先在 dts/upstream/src/arm64/rockchip/rk3588-hinlink-h88k.dts 中添加PCIE网卡节点
// ETH2 RTL8125 pcie2x1l2 pcie@fe190000
&combphy0_ps {
status = "okay";
};

&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
status = "okay";
};

// ETH1 RTL8125 pcie2x1l1 pcie@fe180000
&combphy2_psu {
status = "okay";
};

&pcie2x1l1 {
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
status = "okay";
};

# 然后在配置文件 configs/h88k-rk3588_defconfig 中添加如下配置即可
CONFIG_PCI=y
CONFIG_CMD_PCI=y
CONFIG_PHYLIB=y
CONFIG_RTL8169=y
CONFIG_PCIE_DW_ROCKCHIP=y

  1. 驱动和使用Nvme硬盘设备
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 首先在 dts/upstream/src/arm64/rockchip/rk3588-hinlink-h88k.dts 中添加PCIE Nvme磁盘节点
&pcie30phy {
status = "okay";
};

&pcie3x4 {
reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie30>;
status = "okay";
};

# 然后在配置文件 configs/h88k-rk3588_defconfig 中添加如下配置即可
CONFIG_CMD_NVME=y
CONFIG_NVME_PCI=y

# 如何在U-Boot中使用Nvme磁盘
=> pci enum # 首先需要枚举板中存在的PCIE设备
=> nvme scan # 然后扫描PCIE控制器下存在的设备
=> nvme info # 最后显示PCIE控制器下全部的设备
=> nvme device 1 # 设置当前选择的Nvme磁盘
=> ls nvme 0:1 # 查看指定Nvme磁盘中的文件

  1. 最后将上面这几个PCIE节点集合展示以方便查看或修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
&combphy0_ps {
status = "okay";
};

&combphy1_ps {
status = "okay";
};

&combphy2_psu {
status = "okay";
};

&pcie2x1l0 {
reset-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
status = "okay";
};

&pcie2x1l1 {
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
status = "okay";
};

&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
status = "okay";
};

&pcie30phy {
status = "okay";
};

&pcie3x4 {
reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie30>;
status = "okay";
};

  1. 在U-Boot中查看这些PCIE设备节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
=> pci enum					# 先枚举系统中的所有PCI设备
=> dm tree # 再查看已识别的设备树节点
pci 0 [ + ] pcie_dw_rockchip |-- pcie@fe180000
pci 1 [ + ] pci_bridge_drv | `-- pci_0:0.0
ethernet 1 [ ] eth_rtl8169 | `-- eth_rtl8169
bootdev 3 [ ] eth_bootdev | `-- eth_rtl8169.bootdev
pci 2 [ + ] pcie_dw_rockchip |-- pcie@fe190000
pci 3 [ + ] pci_bridge_drv | `-- pci_2:0.0
ethernet 2 [ ] eth_rtl8169 | `-- eth_rtl8169
bootdev 4 [ ] eth_bootdev | `-- eth_rtl8169.bootdev
......
pci 4 [ + ] pcie_dw_rockchip |-- pcie@fe150000
pci 5 [ + ] pci_bridge_drv | `-- pci_4:0.0
nvme 0 [ ] nvme | `-- nvme#0
pci 6 [ + ] pcie_dw_rockchip |-- pcie@fe170000
pci 7 [ + ] pci_bridge_drv | `-- pci_6:0.0
pci_generi 2 [ ] pci_generic_drv | `-- pci_7:0.0
......
ethernet 0 [ + ] eth_eqos |-- ethernet@fe1b0000
eth_phy_ge 0 [ + ] eth_phy_generic_drv | |-- phy@1
bootdev 2 [ ] eth_bootdev | `-- ethernet@fe1b0000.bootdev


=> pci enum # 强制重新扫描PCIE总线
=> pci d 01.00.00 # 查看总线号为3的设备的配置空间信息
00000000: 812510ec 00100007 02000005 00000008
00000010: f3100001 00000000 40100004 00000000
00000020: 40110004 00000000 00000000 812510ec
00000030: 00000000 00000040 00000000 000001ff

=> pci 0 # 显示总线号为1的PCIe控制器及其连接的外设信息
Scanning PCI devices on bus 0
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
00.00.00 0x1d87 0x3588 Bridge device 0x04
=> pci 1
Scanning PCI devices on bus 1
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
01.00.00 0x10ec 0x8125 Network controller 0x00
=> pci 2
Scanning PCI devices on bus 2
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
02.00.00 0x1d87 0x3588 Bridge device 0x04
=> pci 3
Scanning PCI devices on bus 3
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
03.00.00 0x10ec 0x8125 Network controller 0x00
=> pci 4
Scanning PCI devices on bus 4
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
04.00.00 0x1d87 0x3588 Bridge device 0x04
=> pci 5
Scanning PCI devices on bus 5
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
05.00.00 0x14c3 0x7906 Network controller 0x80
=>

# 在PCI设备上执行总线控制器的操作。它可以用于扫描PCI总线,探测和配置PCI设备,设置中断路由等。这个命令可以用于操作和管理PCI总线上的设备。
=> pci h 01.00.00
vendor ID = 0x10ec
device ID = 0x8125
command register ID = 0x0007
status register = 0x0010
revision ID = 0x05
class code = 0x02 (Network controller)
sub class code = 0x00
programming interface = 0x00
cache line = 0x08
latency time = 0x00
header type = 0x00
BIST = 0x00
base address 0 = 0xf3100001
base address 1 = 0x00000000
base address 2 = 0x40100004
base address 3 = 0x00000000
base address 4 = 0x40110004
base address 5 = 0x00000000
cardBus CIS pointer = 0x00000000
sub system vendor ID = 0x10ec
sub system ID = 0x8125
expansion ROM base address = 0x00000000
interrupt line = 0xff
interrupt pin = 0x01
min Grant = 0x00
max Latency = 0x00
=>

添加USB支持

  1. 查询开发板原厂GPIO配置表得知如下信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# USB3.0-A 口 
⚫ USB3.0接口由USB3.0 HUB转接而来,共计4口USB3.0
⚫ TYPEC1_USB_RX/TX数据线连接到【USB3.0 TYPEC1 PHY】
⚫ TYPEC1_USB_DMDP连接到【USB2.0 TYPEC1 PHY】
⚫ HUB30_RESET连接到【AL27 GPIO4_A6】
⚫ 4个USB共用供电使能引脚【AK26 GPIO4_B0】,输出高电平后USB接口才会输出5V
⚫ 其他GPIO暂时未写,请参考DTS,编译的时候合入

# 另附RK3588的USB控制器在DTS中对应节点名称:
_________________________________________________________________________________________________________________________________
USB接口类型 | USB控制器节点 | USB PHY节点 |
---------------------------------------------------------------------------------------------------------------------------------
USB3.0_TYPEC0 | usbdrd3_0,usbdrd_dwc3_0 xHCI | u2phy0,u2phy0_otg,usbdp_phy0,usbdp_phy0_u3 |
USB3.0_TYPEC1 | usbdrd3_1,usbdrd_dwc3_1 xHCI | u2phy1,u2phy1_otg,usbdp_phy1,usbdp_phy1_u3 |
USB3.0_HOST2 | usbhost3_0,usbhost_dwc3_0 xHCI | combphy2_psu |
USB2.0_HOST0 | usb_host0_ehci,usb_host0_ohci | u2phy2,u2phy2_host |
USB2.0_HOST1 | usb_host1_ehci,usb_host1_ohci | u2phy3,u2phy3_host |
---------------------------------------------------------------------------------------------------------------------------------

# USB控制器节点名称在此定义 "rk3588.dtsi" -> rk3588-extra.dtsi ,不一致的请修改
usb_host0_xhci: usb@fc000000
usb_host0_ehci: usb@fc800000
usb_host0_ohci: usb@fc840000
usb_host1_ehci: usb@fc880000
usb_host1_ohci: usb@fc8c0000
usb_host1_xhci: usb@fc400000 # 对应这个:usbdrd3_1,usbdrd_dwc3_1
usb_host2_xhci: usb@fcd00000
usbdp_phy0: phy@fed80000

# 如下DTS均借鉴自:https://github.com/armbian/linux-rockchip/blob/rk-6.1-rkr5.1/arch/arm64/boot/dts/rockchip/rk3588-hinlink-h88k.dts

  1. 驱动各个USB控制器,如下操作完成可在U-Boot中找到USB但不知道怎么用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 首先在 dts/upstream/src/arm64/rockchip/rk3588-hinlink-h88k.dts 中添加USB节点
// USB2
&u2phy2 {
status = "okay";
};

&u2phy2_host {
status = "okay";
};

&u2phy3 {
status = "okay";
};

&u2phy3_host {
status = "okay";
};

/* 不知为何不能添加OHCI控制器,否则 usb start 时会卡死
&usb_host0_ohci {
status = "okay";
};

&usb_host1_ohci {
status = "okay";
}; */

&usb_host0_ehci {
status = "okay";
};

&usb_host1_ehci {
status = "okay";
};

// USB3
&u2phy0 {
status = "okay";
};

&u2phy0_otg {
vbus-supply = <&vcc5v0_usb_otg>;
status = "okay";
};

&u2phy1 {
status = "okay";
};

&u2phy1_otg {
phy-supply = <&vcc5v0_usb_host>;
status = "okay";
};

&usbdp_phy0 {
status = "okay";
};

&usbdp_phy1 {
status = "okay";
};

&usb_host0_xhci {
dr_mode = "host";
status = "okay";
};

&usb_host1_xhci {
status = "okay";
};

&usb_host2_xhci {
dr_mode = "host";
status = "okay";
};

# 然后在配置文件 configs/h88k-rk3588_defconfig 中添加如下配置即可
CONFIG_CMD_USB=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_GENERIC=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y

  1. 在U-Boot中查看这些USB设备节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
           指令           |           功能
usb start | 初始化USB控制器
usb reset | 重新初始化USB控制器
usb stop [f] | 关闭USB控制器
usb tree | 已连接的USB设备树
usb info [dev] | 显示USB设备[dev]的信息
usb storage | 显示已连接的USB存储设备
usb dev [dev] | 显示和设置当前USB存储设备
usb part [dev] | 显示USB存储设备[dev]的分区信息
usb read addr blk# cnt | 读取USB存储设备数据

=> usb start
starting USB...
Bus usb@fc000000: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
Bus usb@fc800000: USB EHCI 1.00
Bus usb@fc880000: USB EHCI 1.00
Bus usb@fcd00000: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
scanning bus usb@fc000000 for devices... 1 USB Device(s) found
scanning bus usb@fc800000 for devices... 1 USB Device(s) found
scanning bus usb@fc880000 for devices... 1 USB Device(s) found
scanning bus usb@fcd00000 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found

=> usb tree
USB device tree:
1 Hub (5 Gb/s, 0mA)
U-Boot XHCI Host Controller

1 Hub (480 Mb/s, 0mA)
u-boot EHCI Host Controller

1 Hub (480 Mb/s, 0mA)
u-boot EHCI Host Controller

1 Hub (5 Gb/s, 0mA)
U-Boot XHCI Host Controller

=> dm tree
nop 0 [ + ] dwc3-generic-wrapper |-- usb@fc000000
usb 0 [ + ] dwc3-generic-host | `-- usb@fc000000
usb_hub 0 [ + ] usb_hub | `-- usb_hub
usb 1 [ + ] ehci_generic |-- usb@fc800000
usb_hub 1 [ + ] usb_hub | `-- usb_hub
usb 2 [ + ] ehci_generic |-- usb@fc880000
usb_hub 2 [ + ] usb_hub | `-- usb_hub
nop 1 [ + ] dwc3-generic-wrapper |-- usb@fcd00000
usb 3 [ + ] dwc3-generic-host | `-- usb@fcd00000
usb_hub 3 [ + ] usb_hub | `-- usb_hub
......
syscon 10 [ + ] syscon |-- syscon@fd5d0000
phy 0 [ + ] rockchip_usb2phy | `-- usb2phy@0
phy 1 [ + ] rockchip_usb2phy_por | |-- otg-port
clk 3 [ ] rockchip_usb2phy_clo | `-- usb480m_phy0
syscon 11 [ + ] syscon |-- syscon@fd5d8000
phy 2 [ + ] rockchip_usb2phy | `-- usb2phy@8000
phy 3 [ + ] rockchip_usb2phy_por | |-- host-port
clk 4 [ + ] rockchip_usb2phy_clo | `-- usb480m_phy2
syscon 12 [ + ] syscon |-- syscon@fd5dc000
phy 4 [ + ] rockchip_usb2phy | `-- usb2phy@c000
phy 5 [ + ] rockchip_usb2phy_por | |-- host-port
clk 5 [ + ] rockchip_usb2phy_clo | `-- usb480m_phy3
......
nop 2 [ ] dwc3-generic-wrapper |-- usb@fc400000
usb_gadget 0 [ ] dwc3-generic-periphe | `-- usb@fc400000
......
syscon 67 [ ] syscon |-- syscon@fd5d4000
phy 9 [ ] rockchip_usb2phy | `-- usb2phy@4000
phy 10 [ ] rockchip_usb2phy_por | |-- otg-port
clk 7 [ ] rockchip_usb2phy_clo | `-- usb480m_phy1

其他相关技巧

  1. 截取别人的U-Boot自用的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
dd if=nixos-hinlink-h88k.raw of=U-Boot.img bs=1K count=16384		# 首先快速截取前16MB数据
dd if=nixos-hinlink-h88k.raw of=U-Boot.img bs=1K skip=32 count=9511 # 后续慢慢删减掉无效数据

# Linux 下的 hexdump 和 Windows 下的 HxD Hex Editor 均是十六进制文件查看的好工具
leux@B650I:~$ sudo apt install bsdextrautils # 安装十六进制文件查看工具 hexdump,-C 显示16进制和相应的ASCII字符,--skip 跳过多少字节,-n 显示多少字节
leux@B650I:~$ hexdump -C U-Boot.img --skip 32768 # 显示截取的前16MB的十六进制内容,可跳过查看不需要的数据,中间大段空会以 * 显示
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ASCII
------------------------------------------------------------------------------
00008000 52 4b 4e 53 00 00 00 00 80 01 02 00 01 00 00 00 |RKNS............|
......
009519c0 73 62 32 30 00 62 69 6e 6d 61 6e 00 66 69 74 00 |sb20.binman.fit.|
009519d0 72 6e 67 00 00 00 00 00 00 00 00 00 00 00 00 00 |rng.............|
009519e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
01000000 # 可以看到从 0x009519D3 处开始数据就为空了,但后面以从 0x009519E0 处截断为例
leux@B650I:~$
# 先将十六进制值 0x009519E0 转换为十进制得到 9771488 字节,再减去前面需跳过的 32768 字节,最后除以 1024 便得到了截断点
# 即从 (32 * 1024 = 32768) ~ ( 9771488 - 32768 = 9738720 / 1024 = 9510 KB) 处为U-Boot的有效数据,保险起见从 9511KB 处截断
# dd if=nixos-hinlink-h88k.raw of=U-Boot.img bs=1 skip=32768 count=9738720 # 也可直接用字节为单位截取,但速度较慢

# 另外Rockchip U-Boot的数据一般是从 0x00008000 对应的十进制字节位置是 ‌32768 字节‌(即 32KB 处) 开始有效的所以可以跳过无效区域
dd if=openwrt-rockchip-armv8.img of=U-Boot.img bs=1K skip=32 count=9412 # bs 参数默认使用的块大小为 512 字节

# 如果不跳过那个32KB,需要注意的是MBR分区表类型镜像的第一个扇区即前512字节(0x0 ~ 0x000001FF)为MBR主引导记录,也是需要跳过它的
dd if=/dev/sda of=MBR.bin bs=512 count=1 # 导出MBR分区表类型磁盘的主引导记录

  1. U-Boot中通过命令手动加载本地磁盘中的Linux内核和一些其他命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 手动加载Linux内核使Armbian系统启动
=> load mmc 0:1 ${kernel_addr_r} vmlinuz # 加载kernel到指定位置
=> load mmc 0:1 ${ramdisk_addr_r} uInitrd # 加载ramdisk到指定位置
=> load mmc 0:1 ${fdt_addr_r} h88k.dtb # 加载设备树到指定位置
=> setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32,0xfeb50000 root=/dev/mmcblk0p1 rw rootwait"
=> booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} # 启动指定位置的内核


# 其他一些命令及作用
=> reset # 重启
=> poweroff # 关机 CONFIG_CMD_POWEROFF=y > Command line interface > Device access commands > [*] poweroff

# SATA磁盘的使用
=> scsi scan # 扫描SATA控制器下存在的设备
=> scsi info # 显示SATA控制器下全部的设备
=> scsi device 0 # 选择当前的SCSI设备
=> ls scsi 0:1 # 查看指定SCSI设备中的文件

  1. U-Boot中使用TFTP通过网络加载Linux内核
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 在使用TFTP之前,需要确保U-Boot已经配置了正确的网络设置(包括设置开发板的IP地址、子网掩码和服务器的IP地址)
=> setenv serverip 192.168.10.10 # TFTP服务器IP
=> setenv ipaddr 192.168.10.8 # 开发板IP(需同网段)
=> setenv netmask 255.255.255.0 # 子网掩码需一致
=> setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32,0xfeb50000 root=/dev/mmcblk0p1 rw rootwait" # 设置内核启动参数
=> tftp ${kernel_addr_r} vmlinuz # 下载kernel到指定位置
=> tftp ${ramdisk_addr_r} uInitrd # 下载ramdisk到指定位置
=> tftp ${fdt_addr_r} h88k.dtb # 下载设备树到指定位置
=> booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} # 启动指定位置的内核

# 上述操作执行后显示的相关内容如下:
=> tftp ${kernel_addr_r} vmlinuz => tftp ${ramdisk_addr_r} uInitrd => tftp ${fdt_addr_r} h88k.dtb
Using ethernet@fe1b0000 device
TFTP from server 192.168.10.10; our IP address is 192.168.10.8
Filename 'vmlinuz'.
Load address: 0x2000000
......
Filename 'uInitrd'.
Load address: 0x12180000
......
Filename 'h88k.dtb'.
Load address: 0x12000000
......
Loading: #####################################################
6 MiB/s
done
Bytes transferred = 270187 (41f6b hex)
=>


# Linux下可用busybox提供的tftp服务器来测试
leux@B650I:~$ sudo ./busybox-x64 udpsvd -vE 0 69 tftpd -c /mnt/d/u-boot/
udpsvd: listening on 0.0.0.0:69, starting
......
leux@B650I:~$ tree /mnt/d/u-boot/
/mnt/d/u-boot/
├── h88k.dtb
├── uInitrd
└── vmlinuz

1 directory, 3 files
leux@B650I:~$

# Windows下可先按如下设置电脑的静态地址,然后下载Tftpd64:https://github.com/PJO2/tftpd64 程序后选择好根目录和监听网卡即可
# Win32下运行 ncpa.cpl -> 找到与开发板相连的网卡 右键选属性 -> Internet协议版本4 (TCP/IPv4) 属性 -> 使用下面的IP地址 -> IP地址:192.168.10.10 子网掩码:255.255.255.0


=> mii device # 如果有多网卡,可查看当前网卡
MII devices: 'ethernet@fe1b0000' 'ethernet@fe2a0000'
Current device: 'ethernet@fe1b0000'
=>
=> ping 192.168.10.10 # 如果ping不通,请关闭Windows防火墙
ethernet@fe1b0000 Waiting for PHY auto negotiation to complete...... done
Using ethernet@fe1b0000 device
host 192.168.10.10 is alive
=>

适配设备成果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
DDR 9fffbe1e78 cym 24/02/04-10:09:20,fwver: v1.16
LPDDR4X, 2112MHz
channel[0] BW=16 Col=10 Bk=8 CS0 Row=17 CS1 Row=17 CS=2 Die BW=8 Size=4096MB
channel[1] BW=16 Col=10 Bk=8 CS0 Row=17 CS1 Row=17 CS=2 Die BW=8 Size=4096MB
channel[2] BW=16 Col=10 Bk=8 CS0 Row=17 CS1 Row=17 CS=2 Die BW=8 Size=4096MB
channel[3] BW=16 Col=10 Bk=8 CS0 Row=17 CS1 Row=17 CS=2 Die BW=8 Size=4096MB
Manufacturer ID:0x6
CH0 RX Vref:28.5%, TX Vref:21.8%,21.8%
CH1 RX Vref:29.3%, TX Vref:22.8%,23.8%
CH2 RX Vref:28.5%, TX Vref:22.8%,23.8%
CH3 RX Vref:31.0%, TX Vref:22.8%,21.8%
change to F1: 528MHz
change to F2: 1068MHz
change to F3: 1560MHz
change to F0: 2112MHz
out
NOTICE: BL31: v2.12.0(release):b68861c
NOTICE: BL31: Built : 12:27:58, May 17 2025


U-Boot 2025.01 (May 17 2025 - 12:44:00 +0800)

Model: HINLINK H88K
DRAM: 16 GiB
Core: 343 devices, 27 uclasses, devicetree: separate
MMC: mmc@fe2c0000: 0, mmc@fe2e0000: 1
Loading Environment from nowhere... OK
In: serial@feb50000
Out: serial@feb50000
Err: serial@feb50000
Model: HINLINK H88K
Net: eth0: ethernet@fe1b0000
Hit any key to stop autoboot: 0
=> printenv
arch=arm
baudrate=1500000
board=h88k-rk3588
board_name=h88k-rk3588
boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
bootcmd=bootflow scan -lb
bootdelay=2
cpu=armv8
cpuid#=41323443420000000000000000060a03
eth1addr=1a:90:b9:0f:75:b0
ethaddr=1a:90:b9:0f:75:b1
fdt_addr_r=0x12000000
fdtcontroladdr=edbe1f10
fdtfile=rockchip/rk3588-hinlink-h88k.dtb
fdtoverlay_addr_r=0x12100000
kernel_addr_r=0x02000000
kernel_comp_addr_r=0x0a000000
kernel_comp_size=0x8000000
loadaddr=0xc00800
partitions=uuid_disk=${uuid_gpt_disk};name=loader1,start=32K,size=4000K,uuid=${uuid_gpt_loader1};name=loader2,start=8MB,size=4MB,uuid=${uuid_gpt_loader2};name=trust,size=4M,uuid=${uuid_gpt_atf};name=boot,size=112M,bootable,uuid=${uuid_gpt_boot};name=rootfs,size=-,uuid=B921B045-1DF0-41C3-AF44-4C6F280D3FAE;
pxefile_addr_r=0x00e00000
ramdisk_addr_r=0x12180000
script_offset_f=0xffe000
script_size_f=0x2000
scriptaddr=0x00c00000
serial#=82f33c4d7d58cdd8
soc=rk3588
stderr=serial@feb50000
stdin=serial@feb50000
stdout=serial@feb50000
vendor=hinlink

Environment size: 1013/126972 bytes
=>