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

news2024/12/16 22:30:54

本文主要介绍 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_uboot
  clean_opensbi
  clean_rtos
  [[ "$ATF_SRC" == y ]] && clean_atf
  clean_kernel
  clean_ramdisk
  clean_3rd_party
  if [ "$TPU_REL" = 1 ]; then
    clean_ive_sdk
    clean_ivs_sdk
    clean_tpu_sdk
    clean_tdl_sdk
    clean_cnv_sdk
  fi
  clean_middleware
  clean_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 ]; then
    build_tpu_sdk || return $?
    build_ive_sdk || return $?
    build_ivs_sdk || return $?
    build_tdl_sdk  || return $?
  fi
  pack_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_logo
  cd "$BUILD_PATH" || return
  make 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-map

CVI_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.ld

BOARD_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 blmacros

include ${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.env

blmacros-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
endif

fip-dep: bl2 blmacros-env gen-chip-conf


fip_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.coloradmin.cn/o/2260720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解下c语言下的多维数组和指针数组

在实际c语言编程中&#xff0c;三维及以上数组我们使用的很少&#xff0c;二维数组我们使用得较多。说到数组&#xff0c;又不得关联到指针&#xff0c;因为他们两者的联系太紧密了。今天我们就详细介绍下c语言下的多维数组(主要是介绍二维数组)和指针。 一、二维数组 1.1&am…

EXCEL的各种图形,统计图形

目录 0 EXCEL的各种图形&#xff0c;统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图&#xff0c;一般是只选中1列数据&#xff08;1个数组&#xff09; 1.3 如何修改频度图的宽度 1.4 hist图的一个特…

npm内存溢出

项目过大运行项目内存溢出 报错代码 运行内存溢出 increase-memory-limit ‘“node --max-old-space-size8192”’ 不是内部或外部命令&#xff0c;也不是可运行的程序 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of m…

快速部署一套K8s集群-v1.28

快速部署一套K8s集群-v1.28 1.前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式: kubeadmKubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。 二进制包从github下载发行版的二进…

Y3编辑器教程5:触发器进阶使用(镜头、UI、表格、函数库、排行榜、游戏不同步)

文章目录 一、游戏声音设计二、 游戏镜头设计2.1 镜头的基本参数2.2 镜头时间轴动画 三、界面编辑3.1 界面编辑器设置3.2 添加按钮事件3.3 触发编写 四、 表格编辑器&#xff08;实现对话UI&#xff09;4.1 一维表和多维表4.2 数据验证、搜索、保存与撤销4.3 Excel导入导出4.4 …

vue3实现页签

功能点&#xff1a; 新增和删除页签拖拽页签 需要引入插件"vue-draggable-plus": "^0.6.0", 代码已注释右键弹框操作页签左右点击滚动页签和鼠标滑轮滚动页签 注意点 useStore涉及的部分是pina的缓存&#xff0c;需要改成自己的&#xff1b;userStore.tab…

ARCGIS国土超级工具集1.2更新说明

ARCGIS国土超级工具集V1.2版本&#xff0c;功能已增加至47 个。在V1.1的基础上修复了若干使用时发现的BUG&#xff0c;新增了"矢量分割工具"菜单&#xff0c;同时增加及更新了了若干功能&#xff0c;新工具使用说明如下&#xff1a; 一、勘测定界工具栏更新界址点成果…

element-ui实现table表格的嵌套(table表格嵌套)功能实现

最近在做电商类型的官网&#xff0c;希望实现的布局如下&#xff1a;有表头和表身&#xff0c;所以我首先想到的就是table表格组件。 表格组件中常见的就是&#xff1a;标题和内容一一对应&#xff1a; 像效果图中的效果&#xff0c;只用基础的表格布局是不行的&#xff0c;因…

图像分割数据集石头rock分割数据集labelme格式2602张3类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2602 标注数量(json文件个数)&#xff1a;2602 标注类别数&#xff1a;3 标注类别名称:["claystone","silt","…

语音芯片赋能可穿戴设备:开启个性化音频新体验

在科技日新月异的今天&#xff0c;语音芯片与可穿戴设备的携手合作&#xff0c;正引领我们步入一个前所未有的个性化音频时代。这一创新融合&#xff0c;用户可以享受到更加个性化、沉浸式的音频体验。下面将详细介绍语音芯片与可穿戴设备合作的优点和具体应用。 1. 定制化音效…

数据挖掘之聚类分析

聚类分析&#xff08;Clustering Analysis&#xff09; 是数据挖掘中的一项重要技术&#xff0c;旨在根据对象间的相似性或差异性&#xff0c;将对象分为若干组&#xff08;簇&#xff09;。同一簇内的对象相似性较高&#xff0c;而不同簇间的对象差异性较大。聚类分析广泛应用…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(四)

目录 ARC规则 规则 对象型变量不能作为C语言结构体的成员 显式转换id和void* 属性 数组 ARC规则 规则 在ARC有效的情况下编译源代码必须遵守一定的规则&#xff1a; 主要解释一下最后两条 对象型变量不能作为C语言结构体的成员 要把对象型变量加入到结构体成员中时&a…

Java-25 深入浅出 Spring - 实现简易Ioc-01 Servlet介绍 基本代码编写

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

微服务SpringCloud链路追踪之Micrometer+Zipkin

视频教程&#xff1a; https://www.bilibili.com/video/BV12LBFYjEvR 效果演示 当我们发送一个请求给 Gateway 的时候&#xff0c;由 Micrometer trace 进行链路追踪和数据收集&#xff0c;由 Zipkin 进行数据展示。可以清楚的看到微服务的调用过程&#xff0c;以及每个微服务…

【Java】Iterator迭代器相关API

Iterator 是 Java 集合框架中用于遍历集合&#xff08;List、Set 等&#xff09;的工具&#xff0c;它提供了访问集合中每个元素的统一接口&#xff0c;避免直接操作集合的实现细节。 Iterator的基本使用和方法 基本方法 hasNext()&#xff1a;检查是否还有元素可供迭代。ne…

Android 系统应用重名install安装失败分析解决

Android 系统应用重名install安装失败分析解决 文章目录 Android 系统应用重名install安装失败分析解决一、前言1、Android Persistent apps 简单介绍 二、系统 persistent 应用直接安装需求分析解决1、系统应用安装报错返回的信息2、分析解决 三、其他1、persistent系统应用in…

java基础概念49-数据结构2

一、树 1-1、树的基本概念 1、树的节点 2、二叉树 3、树的高度 1-2、二叉查找树 普通二叉树没有规律&#xff0c;不方便查找&#xff0c;没什么作用。 1、基本概念 2、添加节点 此时&#xff0c;该方式添加形成的二叉查找树&#xff0c;根节点就是第一个节点。 3、查找节点 4…

数据仓库工具箱—读书笔记01(数据仓库、商业智能及维度建模初步)

数据仓库、商业智能及维度建模初步 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 博主在这里先把这本书"变薄"~有时间的小伙伴可以亲自再读一读&#xff0c;感受一下…

说说你对java lambda表达式的理解?

大家好&#xff0c;我是锋哥。今天分享关于【说说你对java lambda表达式的理解?】面试题。希望对大家有帮助&#xff1b; 说说你对java lambda表达式的理解? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Java Lambda 表达式是 Java 8 引入的一项重要特性&#…

ambari-server页面错位问题解决

背景&#xff1a; 项目新安装的ambari集群页面错位如下 解决办法&#xff08;临时&#xff09;&#xff1a; 修改ambari-server的前端文件&#xff1a;/usr/lib/ambari-server/web/javascripts/app.js 原代码&#xff1a; initNavigationBar: function () {if (App.get(r…