RK3568设备西瓜皮v3适配immortalwrt

 

适配设备信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# NL68K 西瓜皮V3购买链接:https://item.taobao.com/item.htm?id=711773675433
# MINIPCIE转5G模块转接板:https://item.taobao.com/item.htm?id=694045271626

# 西瓜皮v3硬件配置,包括核心板V3一片,西瓜皮V3底板一片
CPU:瑞芯微 RK3568 四核64位Cortex-A55 Mail-G52 RK817-5
ROM:闪迪 SanDisk SDINBDA4-32G 32GB eMMC
RAM:长鑫 CXMT CXDB5CCBM-MK-A 4GB LPDDR4X

2个 RTL8211F 自带千兆网口
2个 MINIPCIE 接口,带5V电源PA供电专用,可插PCIE的WIFI网卡
1个 M.2 B Key接口,支持RM500Q同尺寸的 5G 模块(52×30×2.3mm)
1个 M.2 E Key接口,支持MT7922同尺寸的WiFi网卡(22x30x2.3mm)
1个 USBA3 OTG接口 1个 HDMI2.0输出接口 1个 TF卡槽 1个 SIM卡槽
1个 DC 5521规格的电源插头,可使用5V-18V 1-3A
1个 FPC接口的 SPI/I2C 显示屏接口,CNC外壳上带的SPI屏幕驱动IC为GC9307
1个 可自动根据CPU温度调节风扇转速的5V风扇接口 MX1.25 4pin PWM调速
3个 LED指示灯 3个按钮:| ⊙ 刷机键 | ↺ 重启键 | ○ 恢复键 |

# 最新消息:西瓜皮V3已于20250813合并到了lean lede项目:https://github.com/coolsnowwolf/lede/commit/8547db9c25d697d9d966f8f8e91c6a74066ff243

获取官方源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 下载源码(--single-branch 仅下载单个分支/标签、--depth=1 只下载最新的一次提交、-b 指定分支/标签)
git clone --depth=1 -b v24.10.2 https://github.com/immortalwrt/immortalwrt
cd immortalwrt/
git pull
./scripts/feeds update -a
./scripts/feeds install -a

make menuconfig # 进入固件配置界面增减改查
make download V=s -j$(nproc) # 请尽量用梯子下载所需源码
make V=s -j$(nproc) # 若编译出错请用单线程调错

# 常用网卡驱动所需驱动包,MT7921有3种版本,E是PCIE,S是SDIO,U是USB,没别的区分。RTL8852也有多种版本
MT7915/MT7916 kmod-mt7915e kmod-mt7915-firmware kmod-mt7916-firmware
MT7921/MT7922/MT7925E kmod-mt7921[e/s/u] kmod-mt7921-firmware kmod-mt7922-firmware kmod-mt7925e kmod-mt7925-firmware
AX500-DBS/NFA765 kmod-ath11k kmod-ath11k-pci ath11k-firmware-qca6390 ath11k-firmware-wcn6855
AX200/AX210/BE200 kmod-iwlwifi iwlwifi-firmware-ax200 iwlwifi-firmware-ax210 iwlwifi-firmware-be200
RTL8852[A/B/C]E/RTL8922AE kmod-rtw89-8852[a/b/c]e rtl8852[a/b/c]e-firmware kmod-rtw89-8922ae rtl8922ae-firmware

# 蓝牙固件
MT7921/MT7922 mt7921bt-firmware mt7922bt-firmware

开始适配设备

  1. target/linux/rockchip/image/armv8.mk 文件最后添加如下内容,使其出现在 make menuconfig 里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# target/linux/rockchip/image/armv8.mk

define Device/nlnet_xiguapi-v3
DEVICE_VENDOR := NLnet
DEVICE_MODEL := XiGuaPi V3
SOC := rk3568
DEVICE_DTS := rockchip/rk3568-xiguapi-v3
UBOOT_DEVICE_NAME := xgp-rk3568
BOOT_FLOW := pine64-img
DEVICE_PACKAGES := wpad-openssl kmod-mt7916-firmware kmod-r8169 kmod-usb-net-rndis \
usbutils pciutils luci luci-ssl-openssl luci-proto-ncm luci-proto-qmi luci-proto-mbim
endef
TARGET_DEVICES += nlnet_xiguapi-v3

  1. 添加适配设备名到指定文件使其可初始化网络和优化网络设备性能,记得不要包含 + 号哦
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
# 将如下带 + 的行添加到:target/linux/rockchip/armv8/base-files/etc/board.d/02_network

rockchip_setup_interfaces()
{
local board="$1"

case "$board" in
+ nlnet,xiguapi-v3|\
armsom,sige7|\
......
rockchip_setup_macs()
{
local board="$1"
local lan_mac=""
local wan_mac=""
local label_mac=""

case "$board" in
+ nlnet,xiguapi-v3|\
armsom,sige3|\

---------------------------------------------------------------------------------------------------
# 将如下带 + 的行添加到:target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity

case "$(board_name)" in
+ nlnet,xiguapi-v3|\
armsom,sige3|\

  1. 在内核源码中为需要适配的设备添加设备树源码文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 将要适配设备的内核设备树源码文件放到指定位置,这样在Immortalwrt构建时该文件便会复制到内核源码中对应的位置
wget -O target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xiguapi-v3.dts \
https://github.com/coolsnowwolf/lede/raw/master/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xiguapi-v3.dts

# 有了DTS还需要在Makefile中添加它,在如下补丁中添加最后那条带 + 的行,建议直接用它替换补丁中已存在的行,使其在编译时应用补丁到内核源码中
---------- target/linux/rockchip/patches-6.6/900-arm64-boot-add-dts-files.patch ----------
diff -Nur a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -114,3 +114,4 @@
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-xiguapi-v3.dtb

  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
27
28
29
30
# 首先在 package/boot/uboot-rockchip/Makefile 中添加本适配设备

define U-Boot/xgp-rk3568
$(U-Boot/rk3568/Default)
NAME:=NLnet XiGuaPi Board
BUILD_DEVICES:= \
nlnet_xiguapi-v3
endef

UBOOT_TARGETS := \
xgp-rk3568 \
......

# 这里使用上面LEDE中别人适配好的内核设备树源码文件并删除其中的rng节点后再作为U-Boot里的设备树源码文件
wget -O package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts \
https://github.com/coolsnowwolf/lede/raw/master/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xiguapi-v3.dts

# 删除第671~674行的rng节点,不删除rng节点编译U-Boot时会报错:Error: arch/arm/dts/.rk3568-xgp.dtb.pre.tmp:671.1-5 Label or path rng not found
sed -i '671,674d' package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts

# 然后U-Boot中的dtsi直接使用Immortalwrt中已支持的相似设备 莱因特T68M 的就行
cp package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-lyt-t68m-u-boot.dtsi package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp-u-boot.dtsi

# 至于U-Boot的配置文件也是直接使用 莱因特T68M 的配置文件再修改部分地方即可
cp package/boot/uboot-rockchip/src/configs/lyt-t68m-rk3568_defconfig package/boot/uboot-rockchip/src/configs/xgp-rk3568_defconfig

# 将上面拷贝的 莱因特T68M 配置文件中的设备树修改为要适配设备的:package/boot/uboot-rockchip/src/configs/xgp-rk3568_defconfig
# CONFIG_DEFAULT_DEVICE_TREE="rk3568-lyt-t68m" 替换为 CONFIG_DEFAULT_DEVICE_TREE="rk3568-xgp"
# CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-lyt-t68m.dtb" 替换为 CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-xiguapi-v3.dtb"

  1. 适配过程中用到的相关变量和文件及解析
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
# target/linux/rockchip/image/armv8.mk
define Device/nlnet_xiguapi-v3 # 该定义的设备名将在 package/boot/uboot-rockchip/Makefile 中被定义设备的 BUILD_DEVICES 内引用
DEVICE_VENDOR := NLnet
DEVICE_MODEL := XiGuaPi V3 # 其在 menuconfig 菜单中显示为 $(DEVICE_VENDOR) + $(DEVICE_MODEL) 即为:NLnet XiGuaPi V3
SOC := rk3568
DEVICE_DTS := rockchip/rk3568-xiguapi-v3 # 指定使用的设备树为 linux/arch/arm64/boot/dts/rockchip/rk3568-xiguapi-v3.dts
UBOOT_DEVICE_NAME := xgp-rk3568 # 指定该设备在U-Boot中对应的设备名为:xgp-rk3568
BOOT_FLOW := pine64-img # 生成镜像使用的分区表及引导相关信息,其在 target/linux/rockchip/image/Makefile 中被定义
DEVICE_PACKAGES := kmod-r8169 # 该设备依赖的软件包,选定该设备即这些软件包将全部包含
endef
TARGET_DEVICES += nlnet_xiguapi-v3 # 添加该设备到 TARGET_DEVICES 中使其可在 menuconfig 菜单中显示

#################################################################################################################################
# package/boot/uboot-rockchip/Makefile
define U-Boot/xgp-rk3568 # 与 armv8.mk 中定义的 UBOOT_DEVICE_NAME 匹配并与同文件后面 UBOOT_TARGETS 中对应
$(U-Boot/rk3568/Default)
NAME:=NLnet XiGuaPi Board # 在 U-Boot 的 menuconfig 菜单中显示的设备名,它在这里并不重要
BUILD_DEVICES:= \
nlnet_xiguapi-v3 # 与 armv8.mk 中定义的设备名 define Device/nlnet_xiguapi-v3 对应
endef

UBOOT_TARGETS := \
xgp-rk3568 \ # 与上面 define U-Boot/xgp-rk3568 定义的设备名相对应

# 在 package/boot/uboot-rockchip/Makefile 中的 define U-Boot/xgp-rk3568 指定了配置文件为:package/boot/uboot-rockchip/src/configs/xgp-rk3568_defconfig
# 在 xgp-rk3568_defconfig 中 CONFIG_DEFAULT_DEVICE_TREE="rk3568-xgp" 指定了其使用的DTS为:package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts
# 在 xgp-rk3568_defconfig 中 CONFIG_DEFAULT_FDT_FILE 指定了U-Boot中变量 ${fdtfile} 的值,但因为在OpenWrt中内核与设备树合并成了 kernel.img 所以也用不上它
# 若 CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3568-xgp" 则DTS文件应位于:package/boot/uboot-rockchip/src/arch/arm/dts/rockchip/rk3568-xgp.dts

# 要是你不用 莱因特T68M 转而使用官方支持的相近配置的设备 Armsom-Sige3 的 u-boot.dtsi 和U-Boot设备树及U-Boot配置文件需要注意如下:
# 拷贝的 Armsom-Sige3 配置文件不修改也能直接用,但因用的是Sige3的设备树,在U-Boot中会显示为:Model: ArmSoM Sige3 但不影响正常启动
# 若不想U-Boot中显示为 Model: ArmSoM Sige3 的话(没啥用,反正也看不见),把上面复制的设备树 rk3568-xgp.dts 中如下字段用西瓜皮的替换即可
# model = "ArmSom Sige3"; model = "NLnet XiGuaPi V3";
# compatible = "armsom,sige3", "rockchip,rk3568"; compatible = "nlnet,xiguapi-v3", "rockchip,rk3568";

# 适配设备U-Boot需要添加修改的相关文件或变量,以 generic-rk3568 设备为例(在本次适配系统中的 u-boot-2024.10 内已包含了 generic-rk3568 设备的如下相关文件)
arch/arm/dts/rk3568-generic.dts
arch/arm/dts/rk3568-generic-u-boot.dtsi
configs/generic-rk3568_defconfig
CONFIG_DEFAULT_DEVICE_TREE="rk3568-generic"
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-generic.dtb"

驱动 SPI屏幕

  1. 自带的SPI屏幕驱动器为GC9307,而它几乎与ST7789V相同,所以这里拿ST7789V模块改下来用

  2. 首先在 immortalwrt/package/kernel/linux/modules/video.mk 中添加如下内容使能在菜单中选择ST7789V内核模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 在 menuconfig 中的位置 > Kernel modules > Video Support > <*> kmod-fb-tft-st7789v

define KernelPackage/fb-tft-st7789v
SUBMENU:=$(VIDEO_MENU)
TITLE:=FB driver for the ST7789V LCD Controller
DEPENDS:=+kmod-fb-tft
KCONFIG:=CONFIG_FB_TFT_ST7789V
FILES:=$(LINUX_DIR)/drivers/staging/fbtft/fb_st7789v.ko
AUTOLOAD:=$(call AutoLoad,09,fb_st7789v)
endef

define KernelPackage/fb-tft-st7789v/description
FB driver for the ST7789V LCD Controller
endef

$(eval $(call KernelPackage,fb-tft-st7789v))

  1. 再将如下内容的补丁放到 immortalwrt/target/linux/rockchip/patches-6.6/999-Add-GC9307.patch 中使内核能驱动这款屏幕
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -28,7 +28,7 @@
"D0 05 0A 09 08 05 2E 44 45 0F 17 16 2B 33\n" \
"D0 05 0A 09 08 05 2E 43 45 0F 16 16 2B 33"

-#define HSD20_IPS 1
+#define HSD20_IPS 0

/**
* enum st7789v_command - ST7789V display controller commands
@@ -289,7 +289,7 @@
default:
return -EINVAL;
}
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x38);
return 0;
}

  1. 还需修改内核设备树中的spi3节点与内核源码文件中的内容相匹配来将设备和驱动绑定起来
1
2
3
4
5
6
7
8
9
10
11
12
13
# 本文中LEDE的dts中已有spi3节点仅需修改其中的 compatible = "galaxycore,gc9307" 为 compatible = "sitronix,st7789v" 即可
# 因为内核源码 drivers/staging/fbtft/fb_st7789v.c 中的如下内容要与dts中spi3节点的 compatible 相匹配
#define DRVNAME "fb_st7789v" // define DRVNAME "fb_gc9307"
......
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display); // FBTFT_REGISTER_DRIVER(DRVNAME, "galaxycore,gc9307", &display);

MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v"); // MODULE_ALIAS("spi:gc9307");
MODULE_ALIAS("platform:st7789v"); // MODULE_ALIAS("platform:gc9307");

MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");

  1. 若使用其他人的设备树需要修改 immortalwrt/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xgp*.dts 中的spi3节点为如下内容
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
......
&spi3 {
pinctrl-names = "default";
pinctrl-0 = <&spi3m1_cs0 &spi3_sck &spi3_mosi>;
status = "okay";
display@0 {
pinctrl-names = "default";
pinctrl-0 = <&spi3_display_dc_pin &display_reset_pin>;
compatible = "sitronix,st7789v";
reg = <0>;
rotate = <270>;
dc-gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;
backlight = <&backlight>;
buswidth = <8>;
debug = <0x0>;
mirror-y;
status = "okay";
};
};
......
&pinctrl {
spi3 {
spi3_sck: spi3_sck {
rockchip,pins = <4 RK_PC2 2 &pcfg_pull_none>;
};
spi3_mosi: spi3_mosi {
rockchip,pins = <4 RK_PC3 2 &pcfg_pull_none>;
};
};

display {
spi3_display_dc_pin: spi3_display_dc_pin {
rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
display_reset_pin: display_reset_pin {
rockchip,pins = <4 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

backlight {
backlight_led_pin: backlight-led-pin {
rockchip,pins = <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
......

  1. 内核显示输出及简单的显示测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@ImmortalWrt:~# dmesg | grep fb
[ 9.233927] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[ 9.251168] fb_st7789v: module is from the staging directory, the quality is unknown, you have been warned.
[ 9.252287] SPI driver fb_st7789v has no spi_device_id for sitronix,st7789v
[ 9.253148] fb_st7789v spi3.0: fbtft_property_value: buswidth = 8
[ 9.253693] fb_st7789v spi3.0: fbtft_property_value: backlight = 157
[ 9.254256] fb_st7789v spi3.0: fbtft_property_value: debug = 0
[ 9.254772] fb_st7789v spi3.0: fbtft_property_value: rotate = 270
[ 9.530937] graphics fb0: fb_st7789v frame buffer, 320x240, 150 KiB video memory, 4 KiB buffer memory, fps=20, spi3.0 at 50 MHz
root@ImmortalWrt:~#

# 提供两个简单的测试方法
cat /dev/urandom > /dev/fb0 # 显示花屏
cat /dev/zero > /dev/fb0 # 清空屏幕,也就是黑屏

# 分享一个适用于西瓜皮v3屏幕的显示程序项目,但其5G模块信息依赖Python3和QModem项目
https://github.com/zzzz0317/xgp-v3-screen/

其他优化项目

  1. 首次开机时自动执行命令和修改配置,根据你的需求及配置修改,这里仅提供简单的示例
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
# 在 /etc/uci-defaults/ 目录中的所有脚本都会被 /etc/init.d/boot 服务自动执行并在成功执行后删除,脚本名称前面的数字大小代表启动顺序
# 它们若没有发生错误的情况下正常结束或以 exit 0 退出后会被删除。而执行失败发生错误以非零代码退出的脚本不会被删除,并将在下次启动时重新执行,直到它们也正常结束
# 更多相关信息请查看:https://openwrt.org/zh/docs/guide-developer/uci-defaults

# 新建 immortalwrt/package/base-files/files/etc/uci-defaults/99-custom 文件内容如下使其首次开机自动配置LAN地址和无线网络

#!/bin/sh
# 设置主机名和时区后提交保存
uci set system.@system[0].hostname="XGP"
uci set system.@system[0].timezone="CST-8"
uci set system.@system[0].zonename="Asia/Shanghai"
uci commit system

# 设置后台地址
uci set network.lan.ipaddr="192.168.100.1"

# 设置第一个无线接口信息为如下,这个不通用请根据你的无线网卡配置来写
uci set wireless.@wifi-device[0].band='5g'
uci set wireless.@wifi-device[0].channel='36'
uci set wireless.@wifi-device[0].country='US'
uci set wireless.@wifi-device[0].htmode='HE80'
uci set wireless.@wifi-device[0].disabled='0'
uci set wireless.@wifi-iface[0].disabled='0'
uci set wireless.@wifi-iface[0].encryption='psk2'
uci set wireless.@wifi-iface[0].ssid="Immortalwrt"
uci set wireless.@wifi-iface[0].key="12345678"
uci commit wireless

/etc/init.d/network reload

  1. 添加QModem移动模组管理程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 添加该项目源码后更新并安装,然后就可以在后面的 menuconfig 中选择构建使用了
echo 'src-git qmodem https://github.com/FUjr/QModem.git;main' >> feeds.conf.default
./scripts/feeds update qmodem
./scripts/feeds install -a -p qmodem

# > LuCI > 3. Applications > <*> luci-app-qmodem
│ │ -*- luci-app-qmodem.............................. LuCI support for QWRT Modem │ │
│ │ Qualcomm QMI WWAN Driver Selection (Vendor QMI driver) ---> │ │
│ │ Quectel Connect Manager Selection (Tom customized Quectel CM) ---> │ │
│ │ [*] Add PCIe Modem SUPPORT │ │
│ │ [*] Add MTK-T7XX Modem PCI SUPPORT │ │
│ │ [*] Add Qfirehose SUPPORT │ │
│ │ < > luci-app-qmodem-hc............................ Luci qwrt modem sim switch │ │
│ │ < > luci-app-qmodem-mwan........................ Luci qwrt modem mwan support │ │
│ │ <*> luci-app-qmodem-sms.......................... Luci qwrt modem sms support │ │
│ │ < > luci-app-qmodem-ttl.......................... Luci qwrt modem ttl support │ │

# 注意:luci-app-qmodem 与 luci-proto-quectel 中的 quectel-cm 中的如下两个依赖包冲突。在 immortalwrt/feeds/packages/net/quectel-cm/Makefile 中有记载
+kmod-usb-net-qmi-wwan-fibocom \
+kmod-usb-net-qmi-wwan-quectel \

  1. 解决EMMC和SD卡均刷OpenWrt后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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 若EMMC和SD卡都用的是OpenWrt中的主线U-Boot 2024.10则会导致SD卡启动时内核用SD卡上的而RootFS依旧用EMMC上的,但分别用不同的就没问题
# 解决方法是EMMC上刷个用Rockchip U-Boot-2017.09的系统,而SD卡则可随意刷OpenWrt U-Boot 2024.10之类的系统,这样OpenWrt在SD卡启动就没问题了

# 我这里刷入创建的空镜像盘来清空EMMC但保留其U-Boot,或者你也可以直接将EMMC刷Armbian系统
dd if=/dev/zero of=zero.img bs=1M count=64 # 创建一个64M的空镜像
losetup -f -P zero.img # 挂载上面创建的空镜像
parted -s /dev/loop0 mklabel gpt # 为镜像创建GPT分区表
parted -s /dev/loop0 mkpart primary ext4 16777216b 100% # 保留前16M后新建分区
mkfs.ext4 /dev/loop0p1 # 格式化分区为EXT4型

# 这里用的是Flippy提供的Rockchip U-Boot-2017.09,想用它引导系统请参考 armbianEnv.txt 那一套,与OpenWrt现在用的有差别
# 刷入读取时需要跳过U-Boot文件前32KB的数据(因为该文件包含未知的分区表信息)。写入时同样跳过空镜像文件前32KB的数据(因其保存的是本镜像的分区表信息)
wget https://github.com/unifreq/openwrt_packit/raw/master/files/rk3568/h68k/bootloader.bin
dd if=bootloader.bin of=/dev/loop0 conv=fsync,notrunc bs=512 skip=64 seek=64 # 镜像写入U-Boot文件
losetup -D # 卸载镜像后即可刷入

———————————————————————————————————————————————————————————————————————————————————————————————
# 说点题外话:RK356X默认u-boot的SPL有个启动次序,比如 MMC1 -> MMC0,而RK356X的MMC又大致分为3种设备:
SDMMC sdmmc用于SD卡通信
SDHCI sdhci用于EMMC通信
SDIO sdio用于wifi等外设通信

# 在源码 u-boot-2024.10/include/configs/rockchip-common.h 中已经定义了默认的启动顺序如下:
#define BOOT_TARGETS "mmc1 mmc0 nvme scsi usb pxe dhcp spi"

# 在源码 u-boot-2024.10/arch/arm/dts/rk356x-u-boot.dtsi 中默认的SPL启动顺序如下:
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc0;
};

chosen {
u-boot,spl-boot-order = "same-as-spl", &sdmmc0, &sdhci;
};

# 所以若是sdhci即EMMC设为mmc0,sdmmc即SD卡设为mmc1,逻辑上看是当有mmc1即SD卡存在时,便会从其启动。SD卡不存在时,则从mmc0启动

# 这些默认定义和启动顺序可能存在但不限于如下等文件中:
u-boot-2024.10/arch/arm/dts/rk356x-u-boot.dtsi
package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts
target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xiguapi-v3.dts
......
  1. 修改构建后系统默认使用的软件源
1
2
3
4
5
# 以将源地址 https://downloads.immortalwrt.org 或 https://mirrors.vsean.net/openwrt 更改为 https://mirrors.cernet.edu.cn/immortalwrt 为例
# 将该文件中 opkg_mirror 值修改为如下即可:immortalwrt/package/emortal/default-settings/files/99-default-settings-chinese
opkg_mirror="https://mirrors.vsean.net/openwrt" 修改为 opkg_mirror="https://mirrors.cernet.edu.cn/immortalwrt"

# 而默认的自定义源存储在:immortalwrt/package/system/opkg/files/customfeeds.conf
  1. 调整内核后缀与immortalwrt官方源中版本一致来使用官方源中的内核模块
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
# 首先请在官方的配置文件上增减软件包,因为官方内核中启用了BTF功能,而自编的没有将导致自编译的系统无法使用官方源中的内核模块
wget -O .config https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/targets/rockchip/armv8/config.buildinfo

# 但官方的配置文件包含了大量我们不需要的选项,它会延长编译时间降低我们的效率,请在 make menuconfig 中按需去除
[ ] Build the OpenWrt Image Builder
[ ] Build the OpenWrt SDK
[ ] Build the LLVM-BPF toolchain tarball
[ ] Package the OpenWrt-based Toolchain
> Global build settings
[ ] Create JSON info file overview per target
[ ] Create CycloneDX SBOM JSON
[ ] Select all target specific packages by default
[ ] Select all kernel module packages by default
[ ] Select all userspace packages by default
[ ] Set build defaults for automatic builds (e.g. via buildbot)

# 然后查看要用的immortalwrt源中内核的版本信息
leux@Debian:~$ curl -s https://downloads.immortalwrt.org/releases/24.10.2/targets/rockchip/armv8/immortalwrt-24.10.2-rockchip-armv8.manifest | grep kernel
kernel - 6.6.93~9e686cc1e0d5129337ca1ca28c2ab984-r1

# 将 immortalwrt/include/kernel-defaults.mk 中第 130 行如下内容注释并在其后添加另一行
......
# grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | $(MKHASH) md5 > $(LINUX_DIR)/.vermagic
cp $(TOPDIR)/.vermagic $(LINUX_DIR)/.vermagic
......

# 将源中内核的后缀添加到immortalwrt源码根目录,后续内核编译时会将其拷贝到内核源码根目录并将其内容作为内核后缀
leux@Debian:~/immortalwrt$ echo "9e686cc1e0d5129337ca1ca28c2ab984" > ~/immortalwrt/.vermagic

# 最后生成的内核包在:~/immortalwrt/bin/targets/rockchip/armv8/packages/kernel_6.6.93~9e686cc1e0d5129337ca1ca28c2ab984-r1_aarch64_generic.ipk

# 刷入该系统后可更换默认软件源为国内源,如下首行KMOD源即是上面后缀一致可用的官方内核模块源
src/gz immortalwrt_kmod https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/targets/rockchip/armv8/kmods/6.6.93-1-9e686cc1e0d5129337ca1ca28c2ab984
src/gz immortalwrt_core https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/targets/rockchip/armv8/packages
src/gz immortalwrt_base https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/packages/aarch64_generic/base
src/gz immortalwrt_luci https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/packages/aarch64_generic/luci
src/gz immortalwrt_packages https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/packages/aarch64_generic/packages
src/gz immortalwrt_routing https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/packages/aarch64_generic/routing
src/gz immortalwrt_telephony https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.2/packages/aarch64_generic/telephony

  1. 将 RM500Q 从 USB 切换到 PCIE,需要用到开头配套的 miniPCIE转5G转接板,先在USB模式下通过AT命令切换成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
# 注意:一旦切换为PCIE模式并重启后,/dev/ttyUSB* 之类的AT端口可能将失效,若你没有让模块支持PCIE模式的接口或转接板,还在USB接口下模块将因失去联系而无法调回

# 这几个指令是模块重启才生效的,而模块PCIE下的驱动需要去上面菜单里面的 luci-app-qmodem 中选择及安装
AT+QCFG="USBNET",0
AT+QCFG="pcie/mode",0 # 默认为 0: EP mode. 1: RC mode. (PCIe运行模式:EP模式:外接设备,用电脑CPU。RC模式:主机模式,用模块的CPU)
AT+QCFG="data_interface",1,0 # 切换为PCIE通信端口,只能是 1,0
AT+QCFG="data_interface",0,0 # 切换为 USB通信端口,只能是 0,0

# 用QModem程序从终端切换为USB和PCIE的命令。若PCIE加载不上,可在计划项里添加:echo 1 > /sys/bus/pci/rescan
tom_modem -d /dev/ttyUSB2 -c 'AT+QCFG="data_interface",0,0'
tom_modem -d /dev/ttyUSB2 -c 'AT+QCFG="data_interface",1,0'

# 出厂默认的为 USB 模式显示如下:
AT+QCFG="pcie/mode" >> /dev/ttyUSB3
AT+QCFG="pcie/mode"

+QCFG: "pcie/mode",0

OK
<<EOF
AT+QCFG="data_interface" >> /dev/ttyUSB3
AT+QCFG="data_interface"

+QCFG: "data_interface",0,0

OK
<<EOF

———————————————————————————————————————————————————————————————————————————————————
接口路径 | 主要功能 | 应用场景 |
———————————————————————————————————————————————————————————————————————————————————
/dev/mhi_BHI | Modem启动和寄存器访问 | 固件加载、硬件调试 |
/dev/mhi_DIAG | 诊断日志传输 | 信号分析、故障排查 |
/dev/mhi_DUN | AT命令交互 | 拨号上网、设接入点 |
/dev/mhi_LOOPBACK | 数据环回测试 | 驱动验证、链路自检 |
/dev/mhi_QMI0 | QMI协议通信 控制 数据 | 模块管理及数据传输 |
———————————————————————————————————————————————————————————————————————————————————

# 若切换PCIE后QModem中总是出现这个错误:【警告! SIM 错误,错误代码:miss】,可尝试关闭SIM卡热插拔
AT+QSIMDET? # 查询当前状态
AT+QSIMDET=0,0 # 关闭热插拔
AT+QSIMDET=1,1 # 开启热插拔,拔插SIM卡会触发状态变更(1,0 表示拔卡)

  1. 关于通过USB接入的FM350-GL在OpenWrt下命令行中手动拨号联网的方法
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
# 部分FM350-GL模块的AT命令及解释
ATI # 查看当前模块信息
AT+GTUSBMODE? # 查询当前模组端口模式,40 RNDIS+AT+AP(GNSS)+META+DEBUG+NPT+ADB,41 RNDIS+AT+AP(GNSS)+META+DEBUG+NPT+ADB+AP(LOG)+AP(META)(default value)
AT+GTUSBMODE=41 # 设置端口模式为41,后续手动拨号联网用的就是这个模式
AT+CGDCONT=3,"IPV4V6","CTNET" # 设置APN,联通 3GNET,电信 CTNET,移动 CMNET
AT+CGACT=1,3 # 激活PDP拨号
AT+CGPADDR=3 # 查看分配的IPv4,然后把这个地址填写到你的RNDIS网卡上,网关为你获取的这个IPv4最后一段更改为 1


# 从这里便开始用命令行手动拨号联网了,首先这里用sendat这个AT工具对 /dev/ttyUSB3 这个端口执行拨号及查看分配的IPv4命令
sendat 3 'AT+CGDCONT=3,"IPV4V6","CTNET"'
sendat 3 'AT+CGACT=1,3'
sendat 3 'AT+CGPADDR=3' # 假设其输出为:+CGPADDR: 3,"10.4.65.212","0.0.0.0.0.0.0.0.24.105.32.53.113.77.169.92"

# 创建名为wwan的IPv4静态地址接口, 物理接口名为FM350在OpenWrt中RNDIS变的eth2,其IP为上面获取到的 "10.4.65.212",网关则为 "10.4.65.1"
ip="10.4.65.212"
gateway="10.4.65.1"
uci set network.wwan=interface
uci set network.wwan.proto=static
uci set network.wwan.ifname=eth2
uci set network.wwan.ipaddr=$ip
uci set network.wwan.gateway=$gateway
uci set network.wwan.netmask=255.255.255.0
uci set network.wwan.dns='114.114.114.114'

# 创建名为wwan6的IPv6接口,若不需要IPv6访问也可不创建
uci set network.wwan6=interface
uci set network.wwan6.proto='dhcpv6'
uci set network.wwan6.ifname='@wwan'
uci set network.wwan6.device='@wwan'
uci set network.wwan6.metric='11'
uci set network.wwan6.extendprefix='1'
uci set network.wwan6.reqaddress='try'
uci set network.wwan6.reqprefix='auto'
uci set network.wwan6.norelease='1'

# 设置完接口外还需要将WWAN等接口防火墙区域设置为WAN才能正常访问互联网
uci del firewall.cfg03dc81.network
uci add_list firewall.cfg03dc81.network='wan'
uci add_list firewall.cfg03dc81.network='wan6'
uci add_list firewall.cfg03dc81.network='wwan'
uci add_list firewall.cfg03dc81.network='wwan6'

# 最后一定要提交保存并重启才能使用
uci commit network
/etc/init.d/network reload

  1. 其他零碎的小知识
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 一个可查询软件包相关信息的网站:https://openwrt.pkgs.org/

# 在 /usr/lib/opkg/status 和 /usr/lib/opkg/info/ 中存储着opkg已安装的软件包相关信息

# 内核补丁目录应用顺序,文件前面数字越小越先应用
Applying /home/leux/openwrt/target/linux/generic/backport-6.6/
Applying /home/leux/openwrt/target/linux/generic/pending-6.6/
Applying /home/leux/openwrt/target/linux/generic/hack-6.6/
Applying /home/leux/openwrt/target/linux/rockchip/patches-6.6/

# 内核中查看相关硬件节点名及其温度
cpu_thermal cat /sys/class/hwmon/hwmon0/name cat /sys/class/hwmon/hwmon0/temp1_input
gpu_thermal cat /sys/class/hwmon/hwmon1/name cat /sys/class/hwmon/hwmon1/temp1_input
ath11k_hwmon cat /sys/class/hwmon/hwmon2/name cat /sys/class/hwmon/hwmon2/temp1_input
mt7915_phy0 cat /sys/class/hwmon/hwmon3/name cat /sys/class/hwmon/hwmon3/temp1_input
mt7915_phy1 cat /sys/class/hwmon/hwmon4/name cat /sys/class/hwmon/hwmon4/temp1_input