从零开始学习 sg200x 多核开发之 sophpi 编译生成 fip.bin 流程梳理

本文主要介绍 sophpi 编译生成 fip.bin 流程。

1、编译前准备

sophpi 的基本编译流程如下:

$ source build/cvisetup.sh
$ defconfig sg2002_wevb_riscv64_sd
$ clean_all
$ build_all
$ pack_burn_image

注:

  1. 需要在 bash 下运行
  2. clean_all 非必要可以不执行。

生成的固件位置: install/soc_sg2002_wevb_riscv64_sd/milkv-duo.img。build_milkv.sh 也是一步一步调用这些函数。

build/cvisetup.sh 通过软链接,链接到 build/envsetup_soc.sh,相关的编译命令都在这个文件中。

build/envsetup_soc.sh 文件中,定义了一些后续编译会用到的变量,如:

  • TOP_DIR=$(gettop)
  • BUILD_PATH=“$TOP_DIR/build”

2、编译入口

总的编译命令,可以不调用 clean_all 函数,不然每次都要全编译。

function clean_all()
{clean_ubootclean_opensbiclean_rtos[[ "$ATF_SRC" == y ]] && clean_atfclean_kernelclean_ramdiskclean_3rd_partyif [ "$TPU_REL" = 1 ]; thenclean_ive_sdkclean_ivs_sdkclean_tpu_sdkclean_tdl_sdkclean_cnv_sdkficlean_middlewareclean_osdrv
}

重点看一下 build_all 函数,位于 build/envsetup_soc.sh 文件中

function build_all()
{(build_uboot || return $?build_kernel || return $?build_ramboot || return $?build_osdrv || return $?build_3rd_party || return $?build_middleware || return $?if [ "$TPU_REL" = 1 ]; thenbuild_tpu_sdk || return $?build_ive_sdk || return $?build_ivs_sdk || return $?build_tdl_sdk  || return $?fipack_cfg || return $?pack_rootfs || return $?pack_data || return $?pack_system || return $?copy_tools || return $?pack_upgrade || return $?
)}

根据上面函数,先调用 build_uboot 函数。

3、uboot编译

  1. build_uboot 函数在 build/milkvsetup.sh 文件中定义
function build_uboot()
{(print_notice "Run ${FUNCNAME[0]}() function"_build_uboot_env_build_opensbi_env_link_uboot_logocd "$BUILD_PATH" || returnmake u-boot || return "$?"
)}
  1. 查看 build/Makefile 文件中 203 行 u-boot 依赖 u-boot-dep
u-boot: u-boot-dep

继续找 u-boot-dep 。。。(文件真多啊。。。)
根据 build/.config 中定义了 CONFIG_FIP_V2=y 找到 build/Makefile 文件

ifeq (${CONFIG_FIP_V1},y)
include scripts/fip_v1.mk
else ifeq (${CONFIG_FIP_V2},y)
include scripts/fip_v2.mk
else
$(error no fip version)
endif

flp_v2.mk

u-boot-dep: fsbl-build ${OUTPUT_DIR}/elf$(call print_target)
ifeq ($(call qstrip,${CONFIG_ARCH}),riscv)${Q}cp ${OPENSBI_PATH}/build/platform/generic/firmware/fw_payload.bin ${OUTPUT_DIR}/fw_payload_uboot.bin${Q}cp ${OPENSBI_PATH}/build/platform/generic/firmware/fw_payload.elf ${OUTPUT_DIR}/elf/fw_payload_uboot.elf
endif
  1. u-boot-dep 又依赖 fsbl-build
    fsbl-build 定义在 scripts/fip_v2.mk 文件
ifeq ($(call qstrip,${CONFIG_ARCH}),riscv)
fsbl-build: opensbi
endif
ifeq (${CONFIG_ENABLE_FREERTOS},y)
fsbl-build: rtos
fsbl%: export BLCP_2ND_PATH=${FREERTOS_PATH}/cvitek/install/bin/cvirtos.bin
fsbl%: export RTOS_DUMP_PRINT_ENABLE=$(CONFIG_ENABLE_RTOS_DUMP_PRINT)
fsbl%: export RTOS_DUMP_PRINT_SZ_IDX=$(CONFIG_DUMP_PRINT_SZ_IDX)
fsbl%: export RTOS_FAST_IMAGE_TYPE=${CONFIG_FAST_IMAGE_TYPE}
fsbl%: export RTOS_ENABLE_FREERTOS=${CONFIG_ENABLE_FREERTOS}
endif
fsbl%: export FSBL_SECURE_BOOT_SUPPORT=${CONFIG_FSBL_SECURE_BOOT_SUPPORT}
fsbl%: export ARCH=$(call qstrip,${CONFIG_ARCH})
fsbl%: export OD_CLK_SEL=${CONFIG_OD_CLK_SEL}
fsbl%: export VC_CLK_OVERDRIVE=${CONFIG_VC_CLK_OVERDRIVE}
fsbl%: export SUSPEND=${CONFIG_SUSPEND}
fsbl%: export TPU_PERF_MODE=$(shell if [ "${CONFIG_CHIP_cv1812cp}" = "y" ] || [ "${CONFIG_CHIP_sg2002}" = "y" ] || [ "${CONFIG_CHIP_cv1812cpa}" = "y" ]; then echo "y";else echo "n";fi)
fsbl%: export BUILD_BOOT0=${CONFIG_ENABLE_BOOT0}
fsbl%: export BUILD_FASTBOOT0=${CONFIG_ENABLE_FASTBOOT0}
fsbl%: export STORAGE=${STORAGE_TYPE}ifeq (${CONFIG_ENABLE_BOOT0},y)
fsbl-build: u-boot-build memory-map$(call print_target)${Q}mkdir -p ${FSBL_PATH}/build${Q}ln -snrf -t ${FSBL_PATH}/build ${CVI_BOARD_MEMMAP_H_PATH}${Q}$(MAKE) -j${NPROC} -C ${FSBL_PATH} O=${FSBL_OUTPUT_PATH}${Q}cp ${FSBL_OUTPUT_PATH}/boot0 ${OUTPUT_DIR}/
else
fsbl-build: u-boot-build memory-map$(call print_target)${Q}mkdir -p ${FSBL_PATH}/build${Q}ln -snrf -t ${FSBL_PATH}/build ${CVI_BOARD_MEMMAP_H_PATH}${Q}$(MAKE) -j${NPROC} -C ${FSBL_PATH} O=${FSBL_OUTPUT_PATH} BLCP_2ND_PATH=${BLCP_2ND_PATH} \LOADER_2ND_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin${Q}cp ${FSBL_OUTPUT_PATH}/fip.bin ${OUTPUT_DIR}/
ifeq (${CONFIG_UBOOT_SPL_CUSTOM},y)${Q}$(MAKE) -C ${FSBL_PATH} clean O=${FSBL_OUTPUT_PATH}${Q}$(MAKE) -j${NPROC} -C ${FSBL_PATH} O=${FSBL_OUTPUT_PATH} BLCP_2ND_PATH=${BLCP_2ND_PATH} \CONFIG_SKIP_UBOOT=$(CONFIG_SKIP_UBOOT) LOADER_2ND_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/spl/u-boot-spl-raw.bin${Q}cp ${FSBL_OUTPUT_PATH}/fip.bin ${OUTPUT_DIR}/fip_spl.bin
else${Q}cp ${FSBL_OUTPUT_PATH}/fip.bin ${OUTPUT_DIR}/fip_spl.bin
endif
endif

又依赖 opensbi

opensbi: export CROSS_COMPILE=$(CONFIG_CROSS_COMPILE_SDK)
opensbi: u-boot-build$(call print_target)${Q}$(MAKE) -j${NPROC} -C ${OPENSBI_PATH} PLATFORM=generic \FW_PAYLOAD_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin \FW_FDT_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/arch/riscv/dts/${CHIP}_${BOARD}.dtb

又依赖 u-boot-build, build/Makefile中定义了 u-boot-build,所以会先执行 u-boot-build

u-boot-build: memory-map
u-boot-build: u-boot-dts
u-boot-build: ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER} ${UBOOT_CVIPART_DEP} ${UBOOT_OUTPUT_CONFIG_PATH}$(call print_target)${Q}ln -snrf ${CVI_BOARD_MEMMAP_H_PATH} ${UBOOT_PATH}/include/${Q}rm -f ${UBOOT_CVI_BOARD_INIT_PATH}${Q}ln -s ${BUILD_PATH}/boards/${CHIP_ARCH_L}/${PROJECT_FULLNAME}/u-boot/cvi_board_init.c ${UBOOT_CVI_BOARD_INIT_PATH}${Q}rm -f ${UBOOT_CVITEK_PATH}${Q}ln -s ${BUILD_PATH}/boards/${CHIP_ARCH_L}/${PROJECT_FULLNAME}/u-boot/cvitek.h ${UBOOT_CVITEK_PATH}${Q}$(MAKE) -j${NPROC} -C ${UBOOT_PATH} olddefconfig${Q}$(MAKE) -j${NPROC} -C ${UBOOT_PATH} all${Q}cat ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot.bin > ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin
ifeq (${CONFIG_UBOOT_SPL_CUSTOM},y)${Q}cat ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/spl/u-boot-spl.bin > ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/spl/u-boot-spl-raw.bin
endif

依赖 memory-map, build/scripts/mmap.mk 中定义了 memory-map

.PHONY: memory-mapCVI_BOARD_MEMMAP_H_PATH := ${BUILD_PATH}/output/${PROJECT_FULLNAME}/cvi_board_memmap.h
CVI_BOARD_MEMMAP_CONF_PATH := ${BUILD_PATH}/output/${PROJECT_FULLNAME}/cvi_board_memmap.conf
CVI_BOARD_MEMMAP_LD_PATH:= ${BUILD_PATH}/output/${PROJECT_FULLNAME}/cvi_board_memmap.ldBOARD_MMAP_PATH := ${BORAD_FOLDER_PATH}/memmap.py
MMAP_CONV_PY := ${BUILD_PATH}/scripts/mmap_conv.py${CVI_BOARD_MEMMAP_H_PATH}: ${BOARD_MMAP_PATH} ${MMAP_CONV_PY}$(call print_target)mkdir -p $(dir $@)@${MMAP_CONV_PY} --type h $< $@${CVI_BOARD_MEMMAP_CONF_PATH}: ${BOARD_MMAP_PATH} ${MMAP_CONV_PY}$(call print_target)@mkdir -p $(dir $@)@${MMAP_CONV_PY} --type conf $< $@${CVI_BOARD_MEMMAP_LD_PATH}: ${BOARD_MMAP_PATH} ${MMAP_CONV_PY}$(call print_target)@mkdir -p $(dir $@)@${MMAP_CONV_PY} --type ld $< $@ifeq ($(wildcard ${BOARD_MMAP_PATH}),)
memory-map:
else
memory-map: ${CVI_BOARD_MEMMAP_H_PATH} ${CVI_BOARD_MEMMAP_CONF_PATH} ${CVI_BOARD_MEMMAP_LD_PATH}
endif

该脚本会自动生成 cvi_board_memmap.hcvi_board_memmap.confcvi_board_memmap.ld 三个文件。

然后依赖 u-boot-dts

u-boot-dts:$(call print_target)
ifeq ($(UBOOT_SRC), u-boot-2021.10)
# U-boot doesn't has arch/arm64
ifeq ($(ARCH), arm64)${Q}find ${BUILD_PATH}/boards/${CHIP_ARCH_L} \\( -path "*linux/*.dts*" -o -path "*dts_${ARCH}/*.dts*" \) \-exec cp {} ${UBOOT_PATH}/arch/arm/dts/ \;${Q}find ${DTS_DEFATUL_PATHS} -name *.dts* -exec cp {} ${UBOOT_PATH}/arch/arm/dts/ \;
else${Q}find ${BUILD_PATH}/boards/${CHIP_ARCH_L} \\( -path "*linux/*.dts*" -o -path "*dts_${ARCH}/*.dts*" \) \-exec cp {} ${UBOOT_PATH}/arch/${ARCH}/dts/ \;${Q}find ${DTS_DEFATUL_PATHS} -name *.dts* -exec cp {} ${UBOOT_PATH}/arch/${ARCH}/dts/ \;
endif
endif

最终执行的命令为:

find sophpi/build/boards/cv181x \\( -path "*linux/*.dts*" -o -path "*dts_riscv/*.dts*" \) \-exec cp {} sophpi/u-boot-2021.10/arch/riscv/dts/ \;
find sophpi/build/boards/default/dts/cv181x sophpi/build/boards/default/dts/cv181x_riscv -name *.dts* -exec cp {} sophpi/u-boot-2021.10/arch/riscv/dts/ \;

sophpi/u-boot-2021.10/arch/riscv/dts 目录下执行 tree 命令,查看相关设备树文件。我们理论上用的是 sg2002 相关的 sg2002_wevb_riscv64_sd.dts 这个文件。

$ tree
.
├── ae350_32.dts
├── ae350_64.dts
├── ae350-u-boot.dtsi
├── binman.dtsi
├── cv1810c_wdmb_0006a_spinor.dts
├── cv1810c_wevb_0006a_spinand.dts
├── cv1810c_wevb_0006a_spinor.dts
├── cv1810h_wevb_0007a_spinor.dts
├── cv1811c_wdmb_0006a_spinor.dts
├── cv1811c_wevb_0006a_emmc.dts
├── cv1811c_wevb_0006a_spinand.dts
├── cv1811c_wevb_0006a_spinor.dts
├── cv1811h_wevb_0007a_emmc.dts
├── cv1811h_wevb_0007a_spinand.dts
├── cv1811h_wevb_0007a_spinor.dts
├── cv1812cp_sophpi_duo_sd.dts
├── cv1812cp_wevb_0006a_emmc.dts
├── cv1812cp_wevb_0006a_spinand.dts
├── cv1812cp_wevb_0006a_spinor.dts
├── cv1812h_wevb_0007a_emmc.dts
├── cv1812h_wevb_0007a_emmc_huashan.dts
├── cv1812h_wevb_0007a_spinand.dts
├── cv1812h_wevb_0007a_spinand_huashan.dts
├── cv1812h_wevb_0007a_spinor.dts
├── cv1812h_wevb_0007a_spinor_huashan.dts
├── cv1813h_wevb_0007a_emmc.dts
├── cv1813h_wevb_0007a_spinand.dts
├── cv1813h_wevb_0007a_spinor.dts
├── cv181x_asic_bga.dtsi
├── cv181x_asic_emmc.dtsi
├── cv181x_asic_qfn.dtsi
├── cv181x_asic_sd.dtsi
├── cv181x_asic_spinand.dtsi
├── cv181x_asic_spinor.dtsi
├── cv181x_base.dtsi
├── cv181x_base_riscv.dtsi
├── cv181x_default_memmap.dtsi
├── fu540-c000.dtsi
├── fu540-c000-u-boot.dtsi
├── fu540-hifive-unleashed-a00-ddr.dtsi
├── fu740-c000.dtsi
├── fu740-c000-u-boot.dtsi
├── fu740-hifive-unmatched-a00-ddr.dtsi
├── hifive-unleashed-a00.dts
├── hifive-unleashed-a00-u-boot.dtsi
├── hifive-unmatched-a00.dts
├── hifive-unmatched-a00-u-boot.dtsi
├── k210.dtsi
├── k210-maix-bit.dts
├── Makefile
├── microchip-mpfs-icicle-kit.dts
├── microchip-mpfs-icicle-kit-u-boot.dtsi
├── openpiton-riscv64.dts
├── qemu-virt.dts
├── sg2000_wevb_riscv64_sd.dts
└── sg2002_wevb_riscv64_sd.dts
  • 执行到这里,才真正开始编译 u-boot,主要是以下几行命令
	${Q}$(MAKE) -j${NPROC} -C ${UBOOT_PATH} olddefconfig${Q}$(MAKE) -j${NPROC} -C ${UBOOT_PATH} all${Q}cat ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot.bin > ${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin

最终产物在 sophpi/u-boot-2021.10/build/sg2002_wevb_riscv64_sd/u-boot-raw.bin

4、opensbi 编译

有了 u-boot 之后,开始编译 opensbi

为了兼容不同的运行需求,OpenSBI 支持三种类型的 Firmware,分别为:

  • dynamic:从上一级 Boot Stage 获取下一级 Boot Stage 的入口信息,以 struct fw_dynamic_info 结构体通过 a2 寄存器传递。
  • jump:假设下一级 Boot Stage Entry 为固定地址,直接跳转过去运行。
  • payload:在 jump 的基础上,直接打包进来下一级 Boot Stage 的 Binary。下一级通常是 Bootloader 或 OS,比如 U-Boot,Linux。

相关编译脚本位置: build/scripts/fip_v2.mk

opensbi: export CROSS_COMPILE=$(CONFIG_CROSS_COMPILE_SDK)
opensbi: u-boot-build$(call print_target)${Q}$(MAKE) -j${NPROC} -C ${OPENSBI_PATH} PLATFORM=generic \FW_PAYLOAD_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin \FW_FDT_PATH=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/arch/riscv/dts/${CHIP}_${BOARD}.dtb

根据以上脚本获知,sophpi 上采用的是 payload 模式,payload 文件为 u-boot-raw.bin,就是上面我们编译出来的文件。
FW_FDT_PATH 为设备树路径,为 sophpi/u-boot-2021.10/build/sg2002_wevb_riscv64_sd/arch/riscv/dts/sg2002_wevb_riscv64_sd.dtb

编译完成后, 产物在 sophpi/opensbi/build/platform/generic/firmware 目录下。

5、fsbl编译

编译完了u-boot 和 opensbi,继续往回推,来到了 fsbl-build。(中间还有一个 rtos 编译,暂时略过先)。
FSBL 是 First Stage Boot Loader 的缩写。

fsbl-build: u-boot-build memory-map$(call print_target)${Q}mkdir -p ${FSBL_PATH}/build${Q}ln -snrf -t ${FSBL_PATH}/build ${CVI_BOARD_MEMMAP_H_PATH}${Q}$(MAKE) -j${NPROC} -C ${FSBL_PATH} O=${FSBL_OUTPUT_PATH}${Q}cp ${FSBL_OUTPUT_PATH}/boot0 ${OUTPUT_DIR}/

最终执行的编译命令为 :

make -j8 -C sophpi/fsbl O=sophpi/fsbl/build/sg2002_wevb_riscv64_sd BLCP_2ND_PATH=sophpi/freertos/cvitek/install/bin/cvirtos.bin \LOADER_2ND_PATH=sophpi/u-boot-2021.10/build/sg2002_wevb_riscv64_sd/u-boot-raw.bin

主要来看看 fsbl 编译流程,从 fsbl/Makefile 文件开始

all: fip bl2 blmacrosinclude ${MAKE_HELPERS_DIRECTORY}fip.mk

依次找到 fip 在 fsbl/make_helpers/fip.mk 文件

gen-chip-conf:$(print_target)${Q}mkdir -p '${BUILD_PLAT}'${Q}./plat/${CHIP_ARCH}/chip_conf.py ${CHIP_CONF_PATH}macro_to_env = ${NM} '${BLMACROS_ELF}' | awk '/DEF_${1}/ { rc = 1; print "${1}=0x" $$1 } END { exit !rc }' >> ${BUILD_PLAT}/blmacros.envblmacros-env: blmacros$(print_target)${Q}> ${BUILD_PLAT}/blmacros.env  # clear .env first${Q}$(call macro_to_env,MONITOR_RUNADDR)${Q}$(call macro_to_env,BLCP_2ND_RUNADDR)
ifeq (${BUILD_BOOT0},y)
$(eval $(call add_define,ENABLE_BOOT0))
fip: fip_boot0
else
fip: fip-all
endiffip-dep: bl2 blmacros-env gen-chip-conffip_boot0: fip-dep$(print_target)${Q}echo "  [GEN] boot0"${Q}. ${BUILD_PLAT}/blmacros.env && \${FIPTOOL} -v genfip \'${BUILD_PLAT}/boot0' \--MONITOR_RUNADDR="$${MONITOR_RUNADDR}" \--BLCP_2ND_RUNADDR="$${BLCP_2ND_RUNADDR}" \--CHIP_CONF='${CHIP_CONF_PATH}' \--NOR_INFO='${NOR_INFO}' \--NAND_INFO='${NAND_INFO}'\--BL2='${BUILD_PLAT}/bl2.bin' \--BLCP_IMG_RUNADDR=${BLCP_IMG_RUNADDR} \--BLCP_PARAM_LOADADDR=${BLCP_PARAM_LOADADDR} \--BLCP=${BLCP_PATH} \--DDR_PARAM='${DDR_PARAM_TEST_PATH}'${Q}echo "  [LS] " $$(ls -l '${BUILD_PLAT}/boot0')${Q}cp ${BUILD_PLAT}/boot0 ${OUTPUT_DIR}fip-simple: fip-dep$(print_target)${Q}echo "  [GEN] fip.bin"${Q}${FIPTOOL} -v genfip \'${BUILD_PLAT}/fip.bin' \--CHIP_CONF='${CHIP_CONF_PATH}' \--NOR_INFO='${NOR_INFO}' \--NAND_INFO='${NAND_INFO}'\--BL2='${BUILD_PLAT}/bl2.bin'${Q}echo "  [LS] " $$(ls -l '${BUILD_PLAT}/fip.bin')

通过一堆复杂的操作。。。生成了一个 bl2.bin 文件。(正常情况下我们开发者也不会去修改这个玩意。。。)

主要关心 fip-all 这个操作,用于生成 fip.bin 文件。

6、fip.bin文件合成

查阅官方有限的资料,获知 fip.bin 为内含 bootloader+uboot 的文件

为啥要这么干?官方的文档里面是这么说的:

由于原生 u-boot 编译出 u-boot.bin 无法直接刻录到 FLASH 中。我们采取 ARM Trusted Firmware Design 中的 Firmware Image Package (FIP) 方式,将 uboot.bin 封装在 FIP.bin 里面。

https://doc.sophgo.com/cvitek-develop-docs/master/docs_latest_release/CV180x_CV181x/zh/01.software/BSP/U-boot_Porting_Development_Guide/build/html/3_U-boot_Transplant.html

通过 chatgpt 查询 fip 后得知:

FIP(Flexible Image Processor)文件是指存储在ARM架构的处理器设备上的固件映像文件。它主要用于引导和配置设备。FIP文件通常包含以下内容:

  1. Trusted Firmware-A(TF-A):TF-A 是 ARM 架构设备上的一个开源的可信固件。它负责设备的引导、安全检查和启动加载程序的执行。
  2. U-Boot:U-Boot 是一个开源的引导加载程序(bootloader),用于启动设备。它提供了引导设备的功能,并提供了配置和管理设备硬件的选项。
  3. ARM Trusted Firmware(ATF):ATF 是一组用于安全引导的固件,用于验证和启动设备上的其他软件组件(如操作系统)。
  4. 其他组件:FIP 文件还可以包含其他固件组件,如设备树(Device Tree)文件、TEE 固件(如 OP-TEE)、加密密钥和配置参数等。
    FIP 文件在 ARM 架构设备上很常见,它们提供了引导和初始化处理器的必要组件。这些文件由设备制造商提供,并根据特定设备、硬件配置和需求进行定制。

按照前面的分析,fip.bin 在 fsbl 最后阶段合成

fip-all: fip-dep$(print_target)${Q}echo "  [GEN] fip.bin"${Q}. ${BUILD_PLAT}/blmacros.env && \${FIPTOOL} -v genfip \'${BUILD_PLAT}/fip.bin' \--MONITOR_RUNADDR="$${MONITOR_RUNADDR}" \--BLCP_2ND_RUNADDR="$${BLCP_2ND_RUNADDR}" \--CHIP_CONF='${CHIP_CONF_PATH}' \--NOR_INFO='${NOR_INFO}' \--NAND_INFO='${NAND_INFO}'\--BL2='${BUILD_PLAT}/bl2.bin' \--BLCP_IMG_RUNADDR=${BLCP_IMG_RUNADDR} \--BLCP_PARAM_LOADADDR=${BLCP_PARAM_LOADADDR} \--BLCP=${BLCP_PATH} \--DDR_PARAM='${DDR_PARAM_TEST_PATH}' \--BLCP_2ND='${BLCP_2ND_PATH}' \--MONITOR='${MONITOR_PATH}' \--LOADER_2ND='${LOADER_2ND_PATH}' \--compress='${FIP_COMPRESS}'${Q}echo "  [LS] " $$(ls -l '${BUILD_PLAT}/fip.bin')

转换成实际执行命令为:

. sophpi/fsbl/build/sg2002_wevb_riscv64_sd/blmacros.env && \
./plat/cv180x/fiptool.py -v genfip \'sophpi/fsbl/build/sg2002_wevb_riscv64_sd/fip.bin' \--MONITOR_RUNADDR="${MONITOR_RUNADDR}" \--BLCP_2ND_RUNADDR="${BLCP_2ND_RUNADDR}" \--CHIP_CONF='sophpi/fsbl/build/sg2002_wevb_riscv64_sd/chip_conf.bin' \--NOR_INFO='FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' \--NAND_INFO='00000000'\--BL2='sophpi/fsbl/build/sg2002_wevb_riscv64_sd/bl2.bin' \--BLCP_IMG_RUNADDR=0x05200200 \--BLCP_PARAM_LOADADDR=0 \--BLCP=test/empty.bin \--DDR_PARAM='test/cv181x/ddr_param.bin' \--BLCP_2ND='sophpi/freertos/cvitek/install/bin/cvirtos.bin' \--MONITOR='../opensbi/build/platform/generic/firmware/fw_dynamic.bin' \--LOADER_2ND='sophpi/u-boot-2021.10/build/sg2002_wevb_riscv64_sd/u-boot-raw.bin' \--compress='lzma'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/492136.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【第二节】Git 工作流程、概念及仓库创建

目录 一、Git 工作流程 二、Git 基本概念 2.1 工作区 2.2 暂存区 2.3 版本库 2.4 操作流程 三、Git 仓库创建 3.1 初始化仓库 3.2 克隆仓库 一、Git 工作流程 Git 的工作流程通常包括以下几个步骤&#xff1a; 1. **克隆 Git 资源**&#xff1a;将远程 Git 仓库克隆到…

概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution

目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点&#xff1a;每个子区间内概率相等 &#xff0c; λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1&#xff1a;用EXCEL计算泊松分布的概率 3 比较λ不同值时…

【机器学习】【无监督学习——聚类】从零开始掌握聚类分析:探索数据背后的隐藏模式与应用实例

从零开始掌握聚类分析&#xff1a;探索数据背后的隐藏模式与应用实例 基本概念聚类分类聚类算法的评价指标&#xff08;1&#xff09;内部指标轮廓系数&#xff08;Silhouette Coefficient&#xff09;DB指数&#xff08;Davies-Bouldin Index&#xff09;Dunn指数 &#xff08…

灵活接入第三方接口,解析第三方json数据,返回我们想要的json格式

需求&#xff1a;我想接入任意第三方http 接口&#xff08;暂不考虑鉴权问题&#xff09;、接口返回任意json数据。 1、要求返回的json数据通过我的R< T > 返回。 2、我的R< T > 里面包含参数 data&#xff0c;code&#xff0c;msg&#xff0c;success标识。 3、…

Nginx 在不同操作系统下的安装指南

Nginx 在不同操作系统下的安装指南 一、Linux 系统下 Nginx 的安装 &#xff08;一&#xff09;基于 Ubuntu 系统 更新软件包列表 打开终端&#xff0c;首先执行sudo apt-get update命令。这一步是为了确保系统的软件包列表是最新的&#xff0c;能够获取到最新版本的 Nginx 及…

docker redis 详细教程

1. 拉取镜像 docker pull redis 2. 创建数据存储目录 cd /home/ mkdir redis cd redis mkdir data mkdir log mkdir conf 3.创建容器并且运行 docker run \ -p 6379:6379 \ --name redis \ -v /home/redis/data:/data \ -d redis 参考链接 史上最详细Docker安装Redis &am…

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …

云计算赋能:TSP 问题求解与创新定价机制的全景剖析

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月18日14点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文源地址&#xff1a; Aspiringco…

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl&#xff0c;方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode&#xff0c;按快捷键CtrlShiftX打开插件市场&#xff0c;搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

QScreen在Qt5.15与Qt6.8版本下的区别

简述 QScreen主要用于提供与屏幕相关的信息。它可以获取有关显示设备的分辨率、尺寸、DPI&#xff08;每英寸点数&#xff09;等信息。本文主要是介绍Qt5.15与Qt6环境下&#xff0c;QScreen的差异&#xff0c;以及如何判断高DPI设备。 属性说明 logicalDotsPerInch&#xff1…

【已解决】在Visual Studio里将应用与Microsoft Store关联时提示网络异常

发布Windows应用时。在Visual Studio里点击"发布“&#xff0c;将应用与Microsoft Store关联时&#xff0c;一直提示网络错误。 查了一下论坛&#xff0c;发现之前也经常出现&#xff0c;但我是第一次遇到。 不能就这样一直被卡着呀&#xff0c;研究了一下&#xff0c;还…

【从零开始入门unity游戏开发之——C#篇10】循环结构——while、do-while、for、foreach的使用

文章目录 一、while 循环1、语法&#xff1a;2、示例&#xff1a; 二、 do-while 循环1、语法&#xff1a;2、示例&#xff1a; 三、for 循环1、语法&#xff1a;2、示例&#xff1a; 四、foreach 循环1、语法&#xff1a;2、示例&#xff1a; 五、总结对比六、注意事项七、使用…

【数据分析】数据结构数据内容概述

文章目录 表格结构数据特征数据类别结构化数据表格结构数据层级表格结构的数据类型单元格的格式属性 表格结构数据获取方法从企业后台数据库系统获取后台数据库系统获取数据流程前端操作平台获取从企业外部渠道获取数据 表格结构数据使用方法单元格值的引用方法单元格区域值的引…

控制策略和算法:两者的类型、应用领域

目录 控制策略类型&#xff1a; 控制算法类型&#xff1a; 应用领域&#xff1a; 其他学术知识 控制策略类型&#xff1a; 开环控制&#xff1a; 在没有反馈的情况下&#xff0c;控制信号是根据对系统模型的预测或设定目标生成的。适用于系统动态特性已知且外部干扰较小的情…

Nacos 3.0 考虑升级到 Spring Boot 3 + JDK 17 了!

Nacos 由阿里开源&#xff0c;是 Spring Cloud Alibaba 中的一个重要组件&#xff0c;主要用于发现、配置和管理微服务。 由于 Spring Boot 2 的维护已于近期停止&#xff0c;Nacos 团队考虑升级到 Spring Boot 3 JDK 17&#xff0c;目前正在征求意见和建议。 这其实是一件好…

【笔记】RT-Thread Studio+STM32CubeMX联合开发,使用SPI+DMA驱动WS2812B RGB灯条,实现单独操控任意灯珠。

硬件平台&#xff1a;STM32L431RCT6 软件版本&#xff1a;RT-Thread Studio 2.2.8&#xff0c;STM32CubeMX 6.12.0 RT-Thread版本&#xff1a;4.1.0 言&#xff1a;之前写过一篇WS2812B的教程&#xff0c;但是最近扒出来用发现不能单独点亮或者熄灭特定位置的灯珠&#xff0c;只…

Vue 中实现节点对齐

Vue 如何将两个 Dom 节点进行对对齐&#xff0c;在前端页面中如何快速的对两个节点元素进行对齐操作&#xff0c;最简单的方式就是使用 Postion&#xff1a;Relative 加 Absolute 实现两个元素的相对位置。今天使用 dom-align 库实现节点对齐&#xff0c;实现以下效果&#xff…

计算机网络-HTTP协议

HTTP HTTP是一种不保存状态&#xff0c;即无状态的协议。HTTP协议自身不对请求和响应之间的通信进行保存。为了保存状态因此后面也有一些技术产生比如Cookies技术。 HTTP是通过URI定位网上的资源&#xff0c;理论上将URI可以访问互联网上的任意资源。 如果不是访问特定的资源…

端到端自动驾驶大模型:视觉-语言-动作模型 VLA

模型框架定义、模型快速迭代能力是考查智驾团队出活能力的两个核心指标。在展开讨论Vision-Language-Action Models(VLA)之前&#xff0c;咱们先来讨论端到端自动驾驶大模型设计。 目录 1. 端到端自动驾驶大模型设计 1.1 模型输入设计 1.2 模型输出设计 1.3 实现难点分析 …

NLP 分词技术浅析

一、NLP 分词技术概述 &#xff08;一&#xff09;定义 自然语言处理&#xff08;NLP&#xff09;中的分词技术是将连续的文本序列按照一定的规则切分成有意义的词语的过程。例如&#xff0c;将句子 “我爱自然语言处理” 切分为 “我”、“爱”、“自然语言处理” 或者 “我…