资讯详情

RK3588 Android平台SPI NOR+PCIE SSD实现大容量存储方案

RK3588 Android平台SPI NOR PCIE SSD实现大容量存储方案

硬件配置

硬件方案是基于RK3588S实现自研平板方案。 CPU: RK3588S DDR: LPDDR5 8GB NOR: SPI接口 32MB容量 SSD: PCIE接口 256GB容量

软件版本要求

软件实现

软件基于RK3588 Android12 SDK实现如下图所示 RK3588 NOR SSD 大容量存储设备启动流程 其中:NOR中存放loader和uboot,RK3588从NOR中加载前级loader,前级loader再引导uboot,在uboot阶段进行SSD主系统的初始化系统;主系统kernel和andorid固件存放在SSD中,由uboot引导启动。 整个启动过程在SDK已经实现了,只需要配置PCIE具体修改如下:

uboot部分

pcie配置根据实际硬件设计进行修改。这里的配置是pcie2.0 x 1lane的接口。

@sys2_206:~/4_Android12_29_sdk/u-boot$ diff --git a/arch/arm/dts/rk3588-u-boot.dtsi b/arch/arm/dts/rk3588-u-boot.dtsi index 3fe8054aac..5894d63a5e 100644 --- a/arch/arm/dts/rk3588-u-boot.dtsi     b/arch/arm/dts/rk3588-u-boot.dtsi @@ -14,7  14,7 @@           chosen { 
                         stdout-path = &uart2; -               u-boot,spl-boot-order = &sdmmc, &sdhci, &spi_nand, &spi_nor;                 u-boot,spl-boot-order = &sdhci, &spi_nand, &spi_nor;         };           secure-otp@fe3a0000 { 
         @@ -22,6  22,33 @@                 compatible = "rockchip,rk3588-secure-otp";                 reg = <0x0 0xfe3a0000 0x0 0x4000>;         };           vcc12v_dcin: vcc12v-dcin { 
                         u-boot,dm-pre-reloc;                 compatible = "regulator-fixed";                 regulator-name = "vcc12v_dcin";                 regulator-always-on;                 regulator-boot-on;                 regulator-min-microvolt = <12000000>;                 regulator-max-microvolt = <12000000>;         };           vcc3v3_pcie20: vcc3v3-pcie20 { 
                         u-boot,dm-pre-reloc;                 compatible = "regulator-fixed";                 regulator-name = "vcc3v3_pcie20";                 reguator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <5000>;
+               vin-supply = <&vcc12v_dcin>;
+       };
+};
+
+&combphy2_psu { 
        
+       u-boot,dm-pre-reloc;
+       status = "okay";
 };
 
 &firmware { 
        
@@ -201,6 +228,13 @@
        u-boot,dm-spl;
 };
 
+&pcie2x1l1 { 
        
+       u-boot,dm-pre-reloc;
+       reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie20>;
+       status = "okay";
+};
+
 &pinctrl { 
        
        u-boot,dm-spl;
        /delete-node/ sdmmc;
diff --git a/configs/rk3588_defconfig b/configs/rk3588_defconfig
index fd6c9114f0..48708dc4c0 100644
--- a/configs/rk3588_defconfig
+++ b/configs/rk3588_defconfig
@@ -223,3 +223,15 @@ CONFIG_RK_AVB_LIBAVB_USER=y
 CONFIG_OPTEE_CLIENT=y
 CONFIG_OPTEE_V2=y
 CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y
+CONFIG_CMD_PCI=y
+CONFIG_NVME=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_DW_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_ROCKCHIP_BOOTDEV="nvme 0"
+CONFIG_EMBED_KERNEL_DTB_ALWAYS=y
+CONFIG_SPL_FIT_IMAGE_KB=2560

因为pcie的配置不是通用的配置,uboot启动的时候需要加在kernel的dtb用来初始化pcie,所以在编译uboot的时候需要把kernel的dtb一起编译到uboot.img中,具体修改是把kernel中编译出来的dtb文件拷贝到uboot/dts/kern.dtb 下面:

@sys2_206:~/4_Android12_29_sdk/u-boot$ cp ../kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s-tablet-ssd.dtb dts/kern.dtb

kernel部分

kernel部分也只要DTS配置PCIE,让PCIE正常工作即可。

@sys2_206:~/4_Android12_29_sdk/kernel-5.10$ vim arch/arm64/boot/dts/rockchip/rk3588s-tablet-ssd.dts 
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
 *
 */

/dts-v1/;

#include "rk3588s-tablet.dtsi"

/ { 
        
        model = "Rockchip RK3588S TABLET SSD Board";
        compatible = "rockchip,rk3588s-tablet-SSD", "rockchip,rk3588";

        vcc3v3_pcie20: vcc3v3-pcie20 { 
        
                compatible = "regulator-fixed";
                regulator-name = "vcc3v3_pcie20";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                enable-active-high;
                gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
                startup-delay-us = <5000>;
                vin-supply = <&vcc5v0_sys>;
        };
};

&chosen { 
        
        bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=1 bootdeay=10";
};

&combphy2_psu { 
        
        status = "okay";
};

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

Android部分

Android中修改存储介质为pcie,用于分区挂载。

@sys2_206:~/4_Android12_29_sdk/device/rockchip/rk3588$ git diff
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -25,7 +25,7 @@ PRODUCT_KERNEL_CONFIG ?= rockchip_defconfig pcie_wifi.config
 
 #BOARD_AVB_ENABLE := true
 # used for fstab_generator, sdmmc controller address
-PRODUCT_BOOT_DEVICE := fe2e0000.mmc
+PRODUCT_BOOT_DEVICE := fe180000.pcie
 PRODUCT_SDMMC_DEVICE := fe2c0000.mmc
 
 SF_PRIMARY_DISPLAY_ORIENTATION := 0

SSD中的存放的固件中不需要uboot和loader分区,所以下面的修改是去掉parameter中的uboot分区

@sys2_206:~/4_Android12_29_sdk/device/rockchip/common$ git diff
diff --git a/build/rockchip/RebuildParameter.mk b/build/rockchip/RebuildParameter.mk
index 4e120e0e..0e04b559 100644
--- a/build/rockchip/RebuildParameter.mk
+++ b/build/rockchip/RebuildParameter.mk
@@ -5,7 +5,7 @@ $(info build parameter.txt with $(PRODUCT_PARAMETER_TEMPLATE)....)
 ifeq ($(strip $(BOARD_USES_AB_IMAGE)), true)
 partition_list := security:4M,uboot_a:4M,trust_a:4M,misc:4M
 else
-partition_list := security:4M,uboot:4M,trust:4M,misc:4M
+partition_list := security:4M,misc:4M
 endif # BOARD_USES_AB_IMAGE
 
 ifeq ($(strip $(BOARD_USES_AB_IMAGE)), true)

SPI-NOR需要一个独立的分区表来配置分区信息,所以单独提供一个parameter_nor.txt文件作为spi-nor的分区表,这个文件放在产品目录下,这里以rk3588s_s为例说明,parameter的内容如下,需要手动拷贝并新建:

@sys2_206:~/4_Android12_29_sdk/device/rockchip/rk3588/rk3588s_s$ vim parameter_nor.txt 
FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: RK3588
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: mtdparts=rk29xxnand:0x00002800@0x00004000(uboot)

以下修改是把parameter_nor.txt 文件在编译的时候拷贝到rockdev下面

@sys2_206:~/4_Android12_29_sdk/device/rockchip/common$ git diff
diff --git a/mkimage.sh b/mkimage.sh
index 69b733e0..288c2456 100755
--- a/mkimage.sh
+++ b/mkimage.sh
@@ -193,6 +193,7 @@ then
 else
     if [ -f $OUT/parameter.txt ]; then
         cp -a $OUT/parameter.txt $IMAGE_PATH/parameter.txt
+        cp -a ${TARGET_DEVICE_DIR}/parameter_nor.txt $IMAGE_PATH/parameter_nor.txt
     else
         echo "$PARAMETER not fount!"
     fi

修改完需要手动把mkimage.sh拷贝替换到SDK根目录下的mkimage.sh

@sys2_206:~/4_Android12_29_sdk$ cp -rf device/rockchip/common/mkimage.sh mkimage.sh

spinor+pcie ssd的固件打包方式跟单独emmc的不一样,需要配置要烧写的固件的存储介质如spinor或者pcie,所以在打包update.img的流程会不一样,下面是打包脚本的修改: 注意:rkImageMaker的版本需要在v2.1及以上的版本

@sys2_206:~/4_Android12_29_sdk/RKTools$ git diff linux/Linux_Pack_Firmware/rockdev/mkupdate.sh
diff --git a/linux/Linux_Pack_Firmware/rockdev/mkupdate.sh b/linux/Linux_Pack_Firmware/rockdev/mkupdate.sh
index 0e00949..7a691dd 100755
--- a/linux/Linux_Pack_Firmware/rockdev/mkupdate.sh
+++ b/linux/Linux_Pack_Firmware/rockdev/mkupdate.sh
@@ -40,8 +40,30 @@ if [ -f "$PACKAGE_FILE" ]; then
 fi
 ./gen-package-file.sh $IMAGE_PATH > $PACKAGE_FILE
 
-echo "start to make update.img..."
+echo "start to make pcie update.img..."
+
 ./afptool -pack ./ $IMAGE_PATH/update.img $PACKAGE_FILE || pause
-./rkImageMaker ${vendor_id_map[$PLATFORM]} $IMAGE_PATH/MiniLoaderAll.bin $IMAGE_PATH/update.img update.img -os_type:androidos || pause
-echo "Making update.img OK."
+./rkImageMaker ${vendor_id_map[$PLATFORM]} $IMAGE_PATH/MiniLoaderAll.bin $IMAGE_PATH/update.img pcie_update.img -os_type:androidos -storage:pcie || pause
+echo "Making $IMAGE_PATH/pcie_update.img OK."
+
+
+echo "regenernate $PACKAGE_FILE..."
+if [ -f "$PACKAGE_FILE" ]; then
+    rm -rf $PACKAGE_FILE
+fi
+cp $IMAGE_PATH/parameter.txt $IMAGE_PATH/parameter.txt.bak
+cp $IMAGE_PATH/parameter_nor.txt $IMAGE_PATH/parameter.txt
+
+./gen-package-file.sh $IMAGE_PATH > $PACKAGE_FILE
+
+echo "start to make spinor update.img..."
+
+./afptool -pack ./ $IMAGE_PATH/update.img $PACKAGE_FILE || pause
+./rkImageMaker ${vendor_id_map[$PLATFORM]} $IMAGE_PATH/MiniLoaderAll.bin $IMAGE_PATH/update.img spinor_update.img -os_type:androidos -storage:spinor || pause
+echo "Making $IMAGE_PATH/spi_update.img OK."
+
+./rkImageMaker -merge ./update.img ./spinor_update.img ./pcie_update.img
+
+
+mv $IMAGE_PATH/parameter.txt.bak $IMAGE_PATH/parameter.txt

以上修改后可以通过build.sh -AUCKu 编译出合并完的update.img,可以直用瑞芯微开发工具进行烧写。

固件烧写

固件分为两个部分:

  • spi-nor里面的固件,需要在maskrom模式下才能升级,烧写loader、uboot、parameter_nor.txt三个固件,烧写时需要在工具中的存储栏中选择存储介质,这里选SOINOR,每个烧写固件都需要选择。 说明:在loader模式下可以通过烧写工具的高级功能切换到maskrom模式:

  • pcie ssd里面的固件,需要在bootloader模式下才能升级,烧写除loader、uboot以外的其他固件,主要parameter是不包含uboot分区的parameter.txt。烧写时需要在工具中的存储栏中选择存储介质,这里选PCIE,每个烧写固件都需要选择。

  • 一次性完整烧写所有的固件,需要在maskrom模式下进行烧写,可以同时烧写spinor和pcie ssd固件

  • 通过update.img烧写,update.img烧写方式与emmc的相同,推荐使用update.img烧写,需要在maskrom模式下烧写,这样才能更新spinor中的固件。

标签: kc120e3e精密电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台