從零開始學習 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.pswp.cn/web/63151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63151.shtml
英文地址,請注明出處:http://en.pswp.cn/web/63151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql客戶端命令

目錄 結束符 ; \g \G 中斷輸入 ctrl c 查看命令列表 help ? (\?) connect (\r) status (\s) delimiter (\d) exit (\q) quit (\q) tee (\T) ?編輯 notee (\t) prompt (\R) source (\.) system (\!) ?編輯 use (\u) help contents 結束符 ; \g \G 當我…

scala隱式函數

1 定義 通常我們所說的隱式函數也稱為 隱式轉換&#xff0c;是使用 implicit 修飾的函數 作用&#xff1a; 可以通過一個隱式函數將一種類型轉變為另一種類型 隱式轉換有兩種應用場景&#xff1a; 類型轉換&#xff0c;隱式轉換為期望類型 類型增強 2 示例 ①&#xff1a;類…

Tomcat原理(4)——嘗試手動Servlet的實現

目錄 一、什么是Servlet 1.servlet的定義 2.servlet的結構 二、實現servlet的流程圖 三、具體實現代碼 1、server 2.實體類request&response 3.HttpServlet抽象類 4.再定義三個servlet進行測試 Tomcat原理&#xff08;3&#xff09;——靜&動態資源以及運行項…

Node.js內置模塊

1.內置模塊 Node.js的中文網參考手冊:https://nodejs.cn//api 幫助文檔 API文檔:查看對應的模塊,左邊是模塊,右邊是模塊的成員 源碼:https://github.com/nodejs/node/tree/main/lib 查看 例如: http.js 創建web服務器的模塊 -->進入源碼中,搜索…

【RAG實戰】RAG與大模型應用

1.1 大模型應用的方向&#xff1a;RAG 1.1.1 什么是RAG 1. 生成式AI 一種能夠生成各類內容的技術&#xff0c;包括文本、圖像、音頻和合成數據。自2022年底ChatGPT在全球范圍內推廣以來&#xff0c;基于Transformer解碼器結構的大模型已能在短時間內為用戶生成高質量的文本、…

基于DeepSpeed Chat詳解 PPO 算法中的actor_loss_fn及其核心參數

詳解 PPO 算法中的 actor_loss_fn 及其核心參數 1. 引言 在強化學習中&#xff0c;PPO&#xff08;Proximal Policy Optimization&#xff0c;近端策略優化&#xff09;算法是一種經典且高效的策略優化方法。它通過重要性采樣&#xff08;Importance Sampling&#xff09;和策…

D3 基礎1

D3 D3.js (Data-Driven Documents) 是一個基于 JavaScript 的庫&#xff0c;用于生成動態、交互式數據可視化。它通過操作文檔對象模型 (DOM) 來生成數據驅動的圖形。官方網站是 https://d3js.org/ <!DOCTYPE html> <html lang"en"><head><me…

基線檢查:Windows安全基線.【手動 || 自動】

基線定義 基線通常指配置和管理系統的詳細描述&#xff0c;或者說是最低的安全要求&#xff0c;它包括服務和應用程序設置、操作系統組件的配置、權限和權利分配、管理規則等。 基線檢查內容 主要包括賬號配置安全、口令配置安全、授權配置、日志配置、IP通信配置等方面內容&…

Python -- Linux中的Matplotlib圖中無法顯示中文 (中文為方框)

目的 用matplotlib生成的圖中文無法正常顯示 方法 主要原因: 沒找到字體 進入windows系統的C:\Windows\Fonts目錄, 復制自己想要的字體 粘貼到Linux服務器中對應python文件所處的文件夾內 設置字體: 設置好字體文件的路徑在需要對字體設置的地方設置字體 效果 中文正常顯…

快速理解類的加載過程

當程序主動使用某個類時&#xff0c;如果該類還未加載到內存中&#xff0c;則系統會通過如下三個步驟來對該類進行初始化&#xff1a; 1.加載&#xff1a;將class文件字節碼內容加載到內存中&#xff0c;并將這些靜態數據轉換成方法區的運行時數據結構&#xff0c;然后生成一個…

搭建 Elasticsearch 集群:完整教程

本文將詳細介紹如何在 Linux 環境下搭建一個 Elasticsearch 集群&#xff0c;涵蓋環境準備、配置優化、服務啟動等多個環節。 一、環境準備 創建安裝目錄 mkdir /es cd /es解壓 Elasticsearch 安裝包 tar -xzf elasticsearch-7.10.1-linux-x86_64.tar.gz -C /es配置環境變量 編…

寶塔-docker拉取寶塔鏡像,并運行寶塔鏡像

寶塔-拉取寶塔鏡像&#xff0c;并運行鏡像 第1步&#xff1a;查詢 docker search btpanel/baota此docker鏡像由堡塔安全官方發布&#xff0c;鏡像版本為寶塔面板9.2.0正式版和9.0.0_lts 穩定版&#xff0c;鏡像會隨著寶塔面板更新。 目前支持x86_64和arm架構可供下載使用 版本…

使用 Valgrind 檢測 C 程序中的內存問題 -基礎教程

內存泄漏是許多 C 語言程序中的常見問題&#xff0c;它不僅會導致程序性能下降&#xff0c;甚至可能讓系統崩潰。為了檢測和修復這些問題&#xff0c;Valgrind 是一個非常強大的工具&#xff0c;它可以幫助我們分析 C 程序中的內存使用情況&#xff0c;檢測內存泄漏、越界訪問、…

窮舉vs暴搜vs深搜vs回溯vs剪枝專題一>子集

題目&#xff1a; 兩個方法本質就是決策樹的畫法不同 方法一解析&#xff1a; 代碼&#xff1a; class Solution {private List<List<Integer>> ret;//返回結果private List<Integer> path;//記錄路徑&#xff0c;注意返回現場public List<List<Int…

leecode雙指針部分題目

leecode雙指針部分題目 1. 驗證回文串2. 判斷子序列3. 兩數之和 II - 輸入有序數組4. 盛最多水的容器5. 三數之和 1. 驗證回文串 如果在將所有大寫字符轉換為小寫字符、并移除所有非字母數字字符之后&#xff0c;短語正著讀和反著讀都一樣。則可以認為該短語是一個 回文串 。 …

Web 應用如何使用sqlite?使用 sql.js 實現前端 SQLite 數據庫操作

前言 在 Web 應用開發中&#xff0c;前端數據處理的重要性日益增加。為了實現更高效的前端數據管理&#xff0c;特別是在處理結構化數據時&#xff0c;sql.js 提供了一個出色的解決方案。sql.js 是將 SQLite 數據庫編譯為 JavaScript 的庫&#xff0c;允許開發者在瀏覽器環境中…

docker 安裝 mysql8.0容器外無法連接

文章目錄 概要問題描述解決方案其他命令 概要 主要是mysql5.7和mysql8.0的兼容性問題。 排查了很久 其實就是配置文件的一句話的事情 感覺mysql8.0更為嚴謹 這樣可能是考慮杜絕一些漏洞吧 問題描述 在容器內 netstat -an | grep 3306 都不行 在容器外 netstat -an | grep 2…

TCP協議簡單分析和握手揮手過程

TCP介紹 TCP是可靠的傳輸層協議&#xff0c;建立連接之前會經歷3次握手的階段。 確認機制&#xff1a;接受方 收到數據之后會向 發送方 回復ACK重傳機制&#xff1a;發送方 在一定時間內沒有收到 接收方的ACK就會重新發送 握手目的&#xff1a;與端口建立連接 TCP的三次握手 …

VisualStudio vsix插件自動加載

本文介紹如何在Visual Studio擴展中實現PackageRegistration&#xff0c;包括設置UseManagedResourcesOnly為true&#xff0c;允許背景加載&#xff0c;并針對C#、VB、F#項目提供自動裝載&#xff0c;附官方文檔鏈接。增加以下特性即可…… [PackageRegistration(UseManagedRe…

opencv所有常見函數

一、opencv圖像操作 二、opencv圖像的數值運算 三、opencv圖像的放射變換 四、opencv空間域圖像濾波 五、圖像灰度化與直方圖 六、形態學圖像處理 七、閾值處理與邊緣檢測 八、輪廓和模式匹配