diff options
| author | jojoandgyc <[email protected]> | 2025-03-27 15:18:56 +0800 |
|---|---|---|
| committer | Rbb666 <[email protected]> | 2025-03-29 08:55:40 +0800 |
| commit | 15ef36747760e7f7e6e1e5c3d0a213fa7d956e21 (patch) | |
| tree | 711a87fddfa28e6093ae20f02cc8a500d67a360c | |
| parent | 1bb18f6e9e69aea9103b9c9f08d78b9d04e14271 (diff) | |
bsp: cvitek: use rttpkgtool for aarch64
Fixed #9968
1.Using scripts in rttpkgtool to make firmware.
2.Deleted duplicate prebuild files.
3.Modify README.md
Signed-off-by: YunZhan Huang <[email protected]>
16 files changed, 36 insertions, 948 deletions
diff --git a/bsp/cvitek/build.sh b/bsp/cvitek/build.sh index c163ccc738..ae89f0c3dc 100755 --- a/bsp/cvitek/build.sh +++ b/bsp/cvitek/build.sh @@ -4,10 +4,11 @@ source ./tools.sh function usage() { echo "Usage:" - echo " ./build.sh [-h|-l|-b]" + echo " ./build.sh [-h|-l|-b|-a]" echo " -h: display usage" echo " -l: build c906L" echo " -b: build c906B" + echo " -a: build Cortex-A53" } function build_c906b() { @@ -28,7 +29,13 @@ function build_c906l() { DPT_PATH_KERNEL=$BSP_PATH/../../ DPT_BOARD_TYPE=$BOARD_TYPE DPT_PATH_OUTPUT=$BSP_PATH/output ./rttpkgtool/script/mkpkg.sh -l } -while getopts ":hbl" opt +function build_a53() { + echo "build_a53 for duo256m" + + DPT_PATH_KERNEL=$BSP_PATH/../../ DPT_BOARD_TYPE=duo256m DPT_PATH_OUTPUT=$BSP_PATH/output DPT_ARCH=arm ./rttpkgtool/script/mkpkg.sh +} + +while getopts ":hbla" opt do case $opt in h) @@ -40,6 +47,9 @@ do l) O_MAKE_LITTLE=y ;; + a) + O_MAKE_ARM=y + ;; ?) echo "Unrecognized parameter." usage @@ -66,3 +76,7 @@ if [ "$O_MAKE_LITTLE" = "y" ]; then build_c906l fi +if [ "$O_MAKE_ARM" = "y" ]; then + build_a53 +fi + diff --git a/bsp/cvitek/cv18xx_aarch64/README.md b/bsp/cvitek/cv18xx_aarch64/README.md index c99db68d6e..ae4028e5b5 100644 --- a/bsp/cvitek/cv18xx_aarch64/README.md +++ b/bsp/cvitek/cv18xx_aarch64/README.md @@ -48,11 +48,9 @@ export RTT_EXEC_PATH=/opt/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin ## 2.3. 执行构建 -首先确保 RISC-V 小核已经构建完成并生成了 `rtthread.bin` 和 `fip.bin`。Duo 256m 的小核是一个 RISC-V 的 core,对应的 bsp 是 `bsp/cvitek/c906_little`。具体构建的说明参考 [bsp cvitek 的 README.md 文件](../README.md)。 +首先确保 RISC-V 小核已经构建完成并生成了 `rtthread.bin` 。Duo 256m 的小核是一个 RISC-V 的 core,对应的 bsp 是 `bsp/cvitek/c906_little`。具体构建的说明参考 [bsp cvitek 的 README.md 文件](../README.md)。构建过后会生成小核的内核镜像文件 `rtthread.bin`,在使用 `rttpkgtool` 制作ARM架构`fip.bin`固件时会使用到。 -`fip.bin` 是一个打包后生成的 bin 文件,包含了 `fsbl`、`uboot` 以及小核的内核镜像文件 `rtthread.bin`。但注意 BSP `c906_little` 构建生成的 `fip.bin` 中的 `fsbl`、`uboot` 这些文件都是 RISC-V 的,所以我们并不能把 BSP `c906_little` 构建生成的 `fip.bin` 直接拿来用于引导启动 ARM 大核。我们这一步只是确保先基于 BSP `c906_little` 做出最新的小核版本 `rtthread.bin`。在下一步构建大核的过程中我们会重新打包更新并生成新的 `fip.bin`,而在重新打包过程中我们需要这个小核的 `rtthread.bin`。 - -这里我们主要关注如何构建 ARM 大核的 `rtthread.bin`。进入 `bsp/cvitek/cv18xx_aarch64` 目录下(记为当前工作目录 `$CWD`),依次执行以下步骤: + `rttpkgtool` 目录下有对应开发板和架构制作固件时所需使用的预编译文件,也可以在 `rttpkgtool` 目录下运行 `./prebuild.sh` 命令来重新制作预编译文件 参考[ rttpkgtool 的 README.md 文件](../rttpkgtool/README.md)。 ### 2.3.1. 开发板选择 @@ -71,7 +69,7 @@ RT-Thread Kernel ---> [*] Enable RT-Thread Smart (microkernel on kernel/userland) ``` -### 2.3.3. 编译大核固件 `boot.sd` +### 2.3.3. 编译固件 ```shell $ scons @@ -80,16 +78,14 @@ $ scons scons 会执行如下步骤的工作: - 如果编译正确无误,在 `$CWD` 下会产生 `rtthread.bin` 文件。 -- 通过运行 `combine.sh`,利用 BSP `cv18xx_aarch64` 下预先提供的、可以在 ARM 核上运行的 `fsbl`、`uboot` 等文件,加上基于 BSP `c906_little` 做出的 `rtthread.bin`,重新打包生成可供 ARM 大核解析和运行的 `fip.bin`。`fip.bin` 会生成在 `$CWD/../output/milkv-duo256m/` 下。 -- 在 `$CWD/../output/milkv-duo256m/` 下生成 `boot.sd` 文件,`boot.sd` 中封装了 ARM 大核对应的 `rtthread.bin`。 - -如果您不关心小核的版本,BSP cv18xx_aarch64 也提供了一个 prebuild 的 `fip.bin`,在 `bsp/cvitek/cv18xx_aarch64/prebuild/milkv-duo256m` 下,直接烧录到 sd-card 中就可以使用。 +- 通过运行 `../build.sh -a` ,利用 rttpkgtool 下提供的可以在 ARM 核上运行的 `fsbl`、`uboot` 等预编译文件,打包生成可供 ARM 大核解析和运行的 `fip.bin`。`fip.bin` 会生成在 `$CWD/../output/milkv-duo256m/` 下。 +- 在 `$CWD/../output/milkv-duo256m/` 下生成 `fip.bin`和`boot.sd` 文件,`fip.bin`中封装了RISCv小核对应的`rtthread.bin`, `boot.sd` 中封装了 ARM 大核对应的 `Image` (与`rtthread.bin`等同)。 # 3. 运行 1. 将 SD 卡分为 2 个分区,第 1 个分区的分区格式为 `FAT32`,用于存放 `fip.bin` 和 `boot.sd` 文件,第 2 个分区可选,如果有可用于作为数据存储分区或者存放文件系统。 -2. 将 `fip.bin` (自己打包生成的或者 prebuild 的) 和编译生成的 `boot.sd` 复制到 SD 卡第一个分区中。`fip.bin` 是小核启动固件,如果只关注 ARM 大核系统,后续只需更新大核的固件,即更新 `boot.sd` 文件即可。 +2. 将 `fip.bin` 和 `boot.sd` 复制到 SD 卡第一个分区中。`fip.bin` 是小核启动固件,如果只关注 ARM 大核系统,后续只需更新大核的固件,即更新 `boot.sd` 文件即可。 3. Duo256M 的大核可以选择使用 RISC-V 或者 ARM,默认使用的是 RISC-V 核,所以这里需要通过短接物理引脚 35(Boot-Switch)和 GND 来切换到 ARM 核,如下图所示。具体参考 [Milk-V Duo 256M 的官方说明](https://milkv.io/zh/docs/duo/getting-started/duo256m#risc-v-%E4%B8%8E-arm-%E5%88%87%E6%8D%A2)。 @@ -97,7 +93,19 @@ scons 会执行如下步骤的工作: 4. 配置 **串口0** 参数: 115200 8N1 ,硬件和软件流控为关。 -直接上电运行,uboot 会自动调用 bootcmd 解析 `boot.sd` 文件,然后加载 `rtthread.bin` 运行。 +开发板上电运行后会先执行BL1 BootROM程序,这段程序是芯片厂烧写在芯片内部,它会加载我们制作的 Fip.bin 固件,也就是从BL2开始往后的代码,运行到BLCP代码段后加载小核的 `rtthread.bin` 运行,运行到 uboot 代码段后会自动调用 bootcmd 解析 `boot.sd` 文件,然后大核加载 `rtthread.bin`运行。 + +SOC双核启动流程如下: +```shell +BL1( BootROM ) + ↓ +BL2( b12.bin ) → 加载BLCP → 初始化协处理器 + | ↓ + ↓ BL3.2( empty.bin ) → 加载小核RT-Thread ( rtthread.bin ) +BL3.1( OpenSBI ) + ↓ +BL3.3( U-Boot ) → 加载大核RT-Thread ( Boot.sd ) +``` ## 3.1. RT-Thread 标准版的例子 diff --git a/bsp/cvitek/cv18xx_aarch64/combine.sh b/bsp/cvitek/cv18xx_aarch64/combine.sh deleted file mode 100755 index 07767e8bba..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/combine.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -C906_LITTLE_BIN_PATH=../c906_little/rtthread.bin -GEN_FIP_PATH=../output/duo256m/ -DEPENDS_FILE_PATH=./prebuild/duo256m - -BLCP_IMG_RUNADDR=0x05200200 -BLCP_PARAM_LOADADDR=0 -NAND_INFO=00000000 -NOR_INFO='FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' -FIP_COMPRESS=lzma - -CHIP_CONF_PATH=${DEPENDS_FILE_PATH}/chip_conf.bin -DDR_PARAM_TEST_PATH=${DEPENDS_FILE_PATH}/ddr_param.bin -BL2_PATH=${DEPENDS_FILE_PATH}/bl2.bin -BLCP_PATH=${DEPENDS_FILE_PATH}/empty.bin -MONITOR_PATH=${DEPENDS_FILE_PATH}/bl31.bin -LOADER_2ND_PATH=${DEPENDS_FILE_PATH}/u-boot-raw.bin - -if [ -f "$C906_LITTLE_BIN_PATH" ]; then - echo "The file $C906_LITTLE_BIN_PATH exist." - BLCP_2ND_PATH=${C906_LITTLE_BIN_PATH} -else - echo "The file $C906_LITTLE_BIN_PATH does not exist. Execute scons to compile it." - exit -fi - -mkdir -p $GEN_FIP_PATH - -echo "Combining fip.bin..." -. ${DEPENDS_FILE_PATH}/blmacros.env && \ -${DEPENDS_FILE_PATH}/fiptool.py -v genfip \ -${GEN_FIP_PATH}/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=${BL2_PATH} \ ---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} - -echo "Combining fip.bin done!" diff --git a/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/multi.its b/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/multi.its deleted file mode 100644 index d3d76fd8ce..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/multi.its +++ /dev/null @@ -1,56 +0,0 @@ -/* - * U-Boot uImage source file with multiple kernels, ramdisks and FDT blobs - */ - -/dts-v1/; - -/ { - description = "Various kernels, ramdisks and FDT blobs"; - #address-cells = <2>; - - images { - kernel-1 { - description = "cvitek kernel"; - data = /incbin/("./Image.lzma"); - type = "kernel"; - arch = "arm64"; - os = "linux"; - compression = "lzma"; - load = <0x0 0x80200000>; - entry = <0x0 0x80200000>; - hash-2 { - algo = "crc32"; - }; - }; - - - /*FDT*/ - - fdt-sg2002_milkv_duo256m_arm_sd { - description = "cvitek device tree - sg2002_milkv_duo256m_arm_sd"; - data = /incbin/("./sg2002_milkv_duo256m_arm_sd.dtb"); - type = "flat_dt"; - arch = "arm64"; - compression = "none"; - hash-1 { - algo = "sha256"; - }; - }; - - - - }; - - /*CFG*/ - configurations { - - config-sg2002_milkv_duo256m_arm_sd { - description = "boot cvitek system with board sg2002_milkv_duo256m_arm_sd"; - kernel = "kernel-1"; - fdt = "fdt-sg2002_milkv_duo256m_arm_sd"; - }; - - }; - - -}; diff --git a/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/sg2002_milkv_duo256m_arm_sd.dtb b/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/sg2002_milkv_duo256m_arm_sd.dtb Binary files differdeleted file mode 100644 index 6ef447d6e2..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/dtb/duo256m/sg2002_milkv_duo256m_arm_sd.dtb +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/mksdimg.sh b/bsp/cvitek/cv18xx_aarch64/mksdimg.sh deleted file mode 100755 index 75c7caf194..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/mksdimg.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -set -e - -PROJECT_PATH=$1 -IMAGE_NAME=$2 - -if [ -z "$PROJECT_PATH" ] || [ -z "$IMAGE_NAME" ]; then - echo "Usage: $0 <PROJECT_DIR> <IMAGE_NAME>" - exit 1 -fi - -ROOT_PATH=$PROJECT_PATH/.. - -source ${ROOT_PATH}/tools.sh - -BOARD_TYPE=`get_board_type $PROJECT_PATH` - -echo "start compress kernel..." - -lzma -c -9 -f -k ${PROJECT_PATH}/${IMAGE_NAME} > ${PROJECT_PATH}/dtb/${BOARD_TYPE}/Image.lzma - -mkdir -p ${ROOT_PATH}/output/${BOARD_TYPE} -mkimage -f ${PROJECT_PATH}/dtb/${BOARD_TYPE}/multi.its -r ${ROOT_PATH}/output/${BOARD_TYPE}/boot.sd - -rm -rf ${PROJECT_PATH}/dtb/${BOARD_TYPE}/Image.lzma diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl2.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl2.bin Binary files differdeleted file mode 100644 index 197e5a1f3a..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl2.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl31.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl31.bin Binary files differdeleted file mode 100644 index cf38b2e291..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/bl31.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/blmacros.env b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/blmacros.env deleted file mode 100644 index ae3059bd57..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/blmacros.env +++ /dev/null @@ -1,2 +0,0 @@ -MONITOR_RUNADDR=0x0000000080000000 -BLCP_2ND_RUNADDR=0x000000008fe00000 diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/chip_conf.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/chip_conf.bin Binary files differdeleted file mode 100644 index d2dabd6868..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/chip_conf.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/ddr_param.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/ddr_param.bin Binary files differdeleted file mode 100644 index fb4c648fd7..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/ddr_param.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/empty.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/empty.bin deleted file mode 100644 index e69de29bb2..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/empty.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fip.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fip.bin Binary files differdeleted file mode 100644 index be1eeeb042..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fip.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fiptool.py b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fiptool.py deleted file mode 100755 index 6943e5f799..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/fiptool.py +++ /dev/null @@ -1,803 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: BSD-3-Clause -# PYTHON_ARGCOMPLETE_OK - -import sys -import logging -import os -import os.path -import argparse -from collections import OrderedDict -import binascii -from struct import pack, unpack -import lzma -import pprint - - -PYTHON_MIN_VERSION = (3, 5, 2) # Ubuntu 16.04 LTS contains Python v3.5.2 by default - - -if sys.version_info < PYTHON_MIN_VERSION: - print("Python >= %r is required" % (PYTHON_MIN_VERSION,)) - sys.exit(-1) - - -try: - import coloredlogs -except ImportError: - coloredlogs = None - -try: - import argcomplete -except ImportError: - argcomplete = None - - -LOADER_2ND_MAGIC_ORIG = b"BL33" -LOADER_2ND_MAGIC_LZMA = b"B3MA" -LOADER_2ND_MAGIC_LZ4 = b"B3Z4" - -LOADER_2ND_MAGIC_LIST = [ - LOADER_2ND_MAGIC_ORIG, - LOADER_2ND_MAGIC_LZMA, - LOADER_2ND_MAGIC_LZ4, -] - -IMAGE_ALIGN = 512 -PARAM1_SIZE = 0x1000 -PARAM1_SIZE_WO_SIG = 0x800 -PARAM2_SIZE = 0x1000 - - -def round_up(divident, divisor): - return ((divident + divisor - 1) // divisor) * divisor - - -def lzma_compress(body): - z = lzma.LZMACompressor(lzma.FORMAT_ALONE, preset=lzma.PRESET_EXTREME) - compressed = z.compress(body) - compressed += z.flush() - - return compressed - - -def lz4_compress(body): - try: - import lz4.frame - except ImportError: - logging.error("lz4 is not installed. Run 'pip install lz4'.") - raise - - compressed = lz4.frame.compress(body) - return compressed - - -class Entry: - __slots__ = "name", "type", "addr", "_content", "entry_size" - - def __init__(self): - self.addr = None - self._content = None - - @property - def end(self): - return self.addr + self.entry_size - - @property - def content(self): - return self._content - - @content.setter - def content(self, value): - if type(value) == int: - value = value.to_bytes(self.entry_size, "little") - - if self.entry_size is not None: - if len(value) > self.entry_size: - raise ValueError("%s (%d bytes) must <= %#r" % (self.name, len(value), self.entry_size)) - value = value + b"\0" * (self.entry_size - len(value)) - - self._content = value - - @classmethod - def make(cls, name, entry_size, _type, init=None): - entry = Entry() - entry.name = name - entry.type = _type - entry.entry_size = entry_size - - if type(init) in (bytes, bytearray): - entry.content = bytes(init) - elif entry_size is not None: - entry.content = b"\0" * entry.entry_size - else: - entry.content = b"" - - return (name, entry) - - def toint(self): - if self.type != int: - raise TypeError("%s is not int type" % self.name) - - return int.from_bytes(self.content, "little") - - def tostr(self): - v = self.content - if self.type == int: - v = "%#08x" % self.toint() - elif type(self.content) in [bytes, bytearray]: - v = v.hex() - if len(v) > 32: - v = v[:32] + "..." - - return v - - def __str__(self): - v = self.tostr() - return "<%s=%s (%dbytes)>" % (self.name, v, self.entry_size) - - def __repr__(self): - v = self.tostr() - return "<%s: a=%#x s=%#x c=%s %r>" % (self.name, self.addr, self.entry_size, v, self.type) - - -class FIP: - param1 = OrderedDict( - [ - Entry.make("MAGIC1", 8, int, b"CVBL01\n\0"), - Entry.make("MAGIC2", 4, int), - Entry.make("PARAM_CKSUM", 4, int), - Entry.make("NAND_INFO", 128, int), - Entry.make("NOR_INFO", 36, int), - Entry.make("FIP_FLAGS", 8, int), - Entry.make("CHIP_CONF_SIZE", 4, int), - Entry.make("BLCP_IMG_CKSUM", 4, int), - Entry.make("BLCP_IMG_SIZE", 4, int), - Entry.make("BLCP_IMG_RUNADDR", 4, int), - Entry.make("BLCP_PARAM_LOADADDR", 4, int), - Entry.make("BLCP_PARAM_SIZE", 4, int), - Entry.make("BL2_IMG_CKSUM", 4, int), - Entry.make("BL2_IMG_SIZE", 4, int), - Entry.make("BLD_IMG_SIZE", 4, int), - Entry.make("PARAM2_LOADADDR", 4, int), - Entry.make("RESERVED1", 4, int), - Entry.make("CHIP_CONF", 760, bytes), - Entry.make("BL_EK", 32, bytes), - Entry.make("ROOT_PK", 512, bytes), - Entry.make("BL_PK", 512, bytes), - Entry.make("BL_PK_SIG", 512, bytes), - Entry.make("CHIP_CONF_SIG", 512, bytes), - Entry.make("BL2_IMG_SIG", 512, bytes), - Entry.make("BLCP_IMG_SIG", 512, bytes), - ] - ) - - body1 = OrderedDict( - [ - Entry.make("BLCP", None, bytes), - Entry.make("BL2", None, bytes), - ] - ) - - param2 = OrderedDict( - [ - Entry.make("MAGIC1", 8, int, b"CVLD02\n\0"), - Entry.make("PARAM2_CKSUM", 4, int), - Entry.make("RESERVED1", 4, bytes), - # DDR param - Entry.make("DDR_PARAM_CKSUM", 4, int), - Entry.make("DDR_PARAM_LOADADDR", 4, int), - Entry.make("DDR_PARAM_SIZE", 4, int), - Entry.make("DDR_PARAM_RESERVED", 4, int), - # BLCP_2ND - Entry.make("BLCP_2ND_CKSUM", 4, int), - Entry.make("BLCP_2ND_LOADADDR", 4, int), - Entry.make("BLCP_2ND_SIZE", 4, int), - Entry.make("BLCP_2ND_RUNADDR", 4, int), - # ATF-BL31 or OpenSBI - Entry.make("MONITOR_CKSUM", 4, int), - Entry.make("MONITOR_LOADADDR", 4, int), - Entry.make("MONITOR_SIZE", 4, int), - Entry.make("MONITOR_RUNADDR", 4, int), - # u-boot - Entry.make("LOADER_2ND_RESERVED0", 4, int), - Entry.make("LOADER_2ND_LOADADDR", 4, int), - Entry.make("LOADER_2ND_RESERVED1", 4, int), - Entry.make("LOADER_2ND_RESERVED2", 4, int), - # Reserved - Entry.make("RESERVED_LAST", 4096 - 16 * 5, bytes), - ] - ) - - body2 = OrderedDict( - [ - Entry.make("DDR_PARAM", None, bytes), - Entry.make("BLCP_2ND", None, bytes), - Entry.make("MONITOR", None, bytes), - Entry.make("LOADER_2ND", None, bytes), - ] - ) - - ldr_2nd_hdr = OrderedDict( - [ - Entry.make("JUMP0", 4, int), - Entry.make("MAGIC", 4, int), - Entry.make("CKSUM", 4, int), - Entry.make("SIZE", 4, int), - Entry.make("RUNADDR", 8, int), - Entry.make("RESERVED1", 4, int), - Entry.make("RESERVED2", 4, int), - ] - ) - - FIP_FLAGS_SCS_MASK = 0x000c - FIP_FLAGS_ENCRYPTED_MASK = 0x0030 - - def _param_size(self, param): - return max((e.end for e in param.values())) - - def _gen_param(self): - addr = 0 - for entry in self.param1.values(): - entry.addr = addr - addr += entry.entry_size - - assert PARAM1_SIZE_WO_SIG == self.param1["BL_PK_SIG"].addr - - addr = 0 - for entry in self.param2.values(): - entry.addr = addr - addr += entry.entry_size - - assert PARAM2_SIZE == self.param2["RESERVED_LAST"].addr + self.param2["RESERVED_LAST"].entry_size - - addr = 0 - for entry in self.ldr_2nd_hdr.values(): - entry.addr = addr - addr += entry.entry_size - - def __init__(self): - self.compress_algo = None - self._gen_param() - - def image_crc(self, image): - crc = binascii.crc_hqx(image, 0) - crc = pack("<H", crc) + b"\xFE\xCA" - return crc - - def pad(self, data, block_size): - if type(data) not in [bytearray, bytes]: - raise TypeError("Need bytearray or bytes") - - r = len(data) % block_size - if r: - data += b"\0" * (block_size - r) - - return data - - def _pprint_attr(self, name): - v = getattr(self, name) - - if type(v) == OrderedDict: - v = list(v.values()) - logging.info("print(%s):\n" % name + pprint.pformat(v, 4, 140)) - - def print_fip_params(self): - self._pprint_attr("param1") - self._pprint_attr("param2") - self._pprint_attr("ldr_2nd_hdr") - - def read_fip(self, path): - logging.debug("read_fip:") - - with open(path, "rb") as fp: - fip_bin = fp.read() - - fip_bin = bytearray(fip_bin) - - e = self.param1["MAGIC1"] - if fip_bin[e.addr : e.end] != e.content: - raise ValueError("Unknown magic %r" % fip_bin[e.addr : e.end]) - - # Read param1 from fip.bin - for e in self.param1.values(): - e.content = fip_bin[e.addr : e.end] - - self.read_end = PARAM1_SIZE - - # Read BLCP - e = self.param1["BLCP_IMG_SIZE"] - blcp_img_size = unpack("<I", fip_bin[e.addr : e.end])[0] - if blcp_img_size: - start = self.read_end - self.read_end = start + blcp_img_size - self.body1["BLCP"].content = fip_bin[start : self.read_end] - - # Read FSBL as BL2 - e = self.param1["BL2_IMG_SIZE"] - bl2_img_size = unpack("<I", fip_bin[e.addr : e.end])[0] - if bl2_img_size: - start = self.read_end - self.read_end = start + bl2_img_size - self.body1["BL2"].content = fip_bin[start : self.read_end] - - logging.info("read_fip end=%#x", self.read_end) - self.rest_fip = fip_bin[self.read_end :] - - self.read_fip2(fip_bin) - - def read_fip2(self, fip_bin): - param2_loadaddr = self.param1["PARAM2_LOADADDR"].toint() - param2_bin = fip_bin[param2_loadaddr : param2_loadaddr + PARAM2_SIZE] - - for e in self.param2.values(): - e.content = param2_bin[e.addr : e.end] - - self.read_end = param2_loadaddr + PARAM2_SIZE - - # Read DDR_PARAM, BLCP_2ND, and MONITOR - for name in ["DDR_PARAM", "BLCP_2ND", "MONITOR"]: - size = self.param2[name + "_SIZE"].toint() - loadaddr = self.param2[name + "_LOADADDR"].toint() - self.body2[name].content = fip_bin[loadaddr : loadaddr + size] - self.read_end = loadaddr + size - - # Read LOADER_2ND - loader_2nd_loadaddr = self.param2["LOADER_2ND_LOADADDR"].toint() - if loader_2nd_loadaddr: - self.read_loader_2nd(fip_bin) - - logging.info("read_fip2 end=%#x", self.read_end) - self.rest_fip = fip_bin[self.read_end :] - - def read_loader_2nd(self, fip_bin): - loader_2nd_loadaddr = self.param2["LOADER_2ND_LOADADDR"].toint() - - self._parse_ldr_2nd_hdr(fip_bin[loader_2nd_loadaddr:]) - - if self.ldr_2nd_hdr["MAGIC"].content not in LOADER_2ND_MAGIC_LIST: - raise ValueError("%r" % self.ldr_2nd_hdr["MAGIC"].content) - - ldr_2nd_size = self.ldr_2nd_hdr["SIZE"].toint() - - self.body2["LOADER_2ND"].content = fip_bin[loader_2nd_loadaddr : loader_2nd_loadaddr + ldr_2nd_size] - - self.read_end = loader_2nd_loadaddr + ldr_2nd_size - self.rest_fip = fip_bin[self.read_end :] - - def add_chip_conf(self, args): - logging.debug("add_chip_conf:") - - with open(args.CHIP_CONF, "rb") as fp: - image = fp.read() - - if image.startswith(b"APLB"): - image = image[8:] # strip old BLP header - - self.param1["CHIP_CONF"].content = image - - def add_blcp(self, args): - logging.debug("add_blcp:") - - with open(args.BLCP, "rb") as fp: - image = fp.read() - - image = self.pad(image, IMAGE_ALIGN) - - self.param1["BLCP_IMG_RUNADDR"].content = args.BLCP_IMG_RUNADDR - self.body1["BLCP"].content = image - - def add_bl2(self, args): - logging.debug("add_bl2:") - - with open(args.BL2, "rb") as fp: - image = fp.read() - - bl2_fill = 0 - if args.BL2_FILL: - bl2_fill = args.BL2_FILL - - image += b"\xA9" * (bl2_fill - len(image)) - image = self.pad(image, IMAGE_ALIGN) - - self.body1["BL2"].content = image - - def add_nor_info(self, args): - logging.debug("add_nor_info:") - self.param1["NOR_INFO"].content = args.NOR_INFO - - def add_nand_info(self, args): - logging.debug("add_nand_info:") - self.param1["NAND_INFO"].content = args.NAND_INFO - - def update_param1_cksum(self, image): - image = bytearray(image) - crc = self.image_crc(image[self.param1["NAND_INFO"].addr : PARAM1_SIZE_WO_SIG]) - - param_cksum = self.param1["PARAM_CKSUM"] - param_cksum.content = crc - image[param_cksum.addr : param_cksum.end] = crc - return image - - def make_fip1(self): - logging.debug("make_fip1:") - - chip_conf = self.param1["CHIP_CONF"].content - self.param1["CHIP_CONF_SIZE"].content = len(chip_conf) - - blcp = self.body1["BLCP"].content - self.param1["BLCP_IMG_CKSUM"].content = self.image_crc(blcp) - self.param1["BLCP_IMG_SIZE"].content = len(blcp) - - bl2 = self.body1["BL2"].content - self.param1["BL2_IMG_CKSUM"].content = self.image_crc(bl2) - self.param1["BL2_IMG_SIZE"].content = len(bl2) - - # Pack body1 - body1_bin = b"" - for entry in self.body1.values(): - if len(entry.content) % IMAGE_ALIGN: - raise ValueError("%s (%d) is not align to %d" % (entry.name, len(entry.content), IMAGE_ALIGN)) - - logging.info("add %s (%#x)", entry.name, len(entry.content)) - body1_bin += entry.content - - logging.debug("len(body1_bin) is %d", len(body1_bin)) - - # Param1 cksum - param1_bin = b"".join((entry.content for entry in self.param1.values())) - param1_bin = self.update_param1_cksum(param1_bin) - - if len(param1_bin) != PARAM1_SIZE: - raise ValueError("param1_bin is %d bytes" % len(param1_bin)) - - fip1_bin = param1_bin + body1_bin - logging.debug("len(fip1_bin) is %d", len(fip1_bin)) - - return fip1_bin - - def add_ddr_param(self, args): - with open(args.DDR_PARAM, "rb") as fp: - ddr_param = fp.read() - - logging.debug("ddr_param=%#x bytes", len(ddr_param)) - self.body2["DDR_PARAM"].content = ddr_param - - def add_blcp_2nd(self, args): - with open(args.BLCP_2ND, "rb") as fp: - blcp_2nd = fp.read() - - logging.debug("blcp_2nd=%#x bytes", len(blcp_2nd)) - self.body2["BLCP_2ND"].content = blcp_2nd - - def add_monitor(self, args): - with open(args.MONITOR, "rb") as fp: - monitor = fp.read() - - logging.debug("monitor=%#x bytes", len(monitor)) - self.body2["MONITOR"].content = monitor - - def add_loader_2nd(self, args): - with open(args.LOADER_2ND, "rb") as fp: - loader_2nd = fp.read() - - logging.debug("loader_2nd=%#x bytes", len(loader_2nd)) - - e = self.ldr_2nd_hdr["MAGIC"] - magic = loader_2nd[e.addr : e.end] - if magic != LOADER_2ND_MAGIC_ORIG: - raise ValueError("loader_2nd's magic should be %r, but %r" % (LOADER_2ND_MAGIC_ORIG, magic)) - - self.compress_algo = args.compress - self.body2["LOADER_2ND"].content = loader_2nd - - def pack_ddr_param(self, fip_bin): - if not len(self.body2["DDR_PARAM"].content): - return - - fip_bin = self.pad(fip_bin, IMAGE_ALIGN) - - # Pack DDR_PARAM to body2 - ddr_param = self.pad(self.body2["DDR_PARAM"].content, IMAGE_ALIGN) - - self.param2["DDR_PARAM_CKSUM"].content = self.image_crc(ddr_param) - self.param2["DDR_PARAM_SIZE"].content = len(ddr_param) - self.param2["DDR_PARAM_LOADADDR"].content = len(fip_bin) - - return fip_bin + ddr_param - - def pack_blcp_2nd(self, fip_bin, blcp_2nd_runaddr): - logging.debug("pack_blcp_2nd:") - if not len(self.body2["BLCP_2ND"].content): - return - - runaddr = int(blcp_2nd_runaddr) - - fip_bin = self.pad(fip_bin, IMAGE_ALIGN) - - # Pack MONITOR to body2 - body = self.pad(self.body2["BLCP_2ND"].content, IMAGE_ALIGN) - - self.param2["BLCP_2ND_CKSUM"].content = self.image_crc(body) - self.param2["BLCP_2ND_SIZE"].content = len(body) - self.param2["BLCP_2ND_LOADADDR"].content = len(fip_bin) - self.param2["BLCP_2ND_RUNADDR"].content = runaddr - - return fip_bin + body - - def pack_monitor(self, fip_bin, monitor_runaddr): - logging.debug("pack_monitor:") - if not len(self.body2["MONITOR"].content): - return - - monitor_runaddr = int(monitor_runaddr) - - fip_bin = self.pad(fip_bin, IMAGE_ALIGN) - - # Pack MONITOR to body2 - monitor = self.pad(self.body2["MONITOR"].content, IMAGE_ALIGN) - - self.param2["MONITOR_CKSUM"].content = self.image_crc(monitor) - self.param2["MONITOR_SIZE"].content = len(monitor) - self.param2["MONITOR_LOADADDR"].content = len(fip_bin) - self.param2["MONITOR_RUNADDR"].content = monitor_runaddr - - return fip_bin + monitor - - def _parse_ldr_2nd_hdr(self, image): - for e in self.ldr_2nd_hdr.values(): - e.content = image[e.addr : e.end] - - def _update_ldr_2nd_hdr(self): - image = self.body2["LOADER_2ND"].content - hdr_size = self._param_size(self.ldr_2nd_hdr) - hdr, body = image[:hdr_size], image[hdr_size:] - - # Update SIZE - self.ldr_2nd_hdr["SIZE"].content = len(image) - - # Update CKSUM - hdr = bytearray(b"".join((e.content for e in self.ldr_2nd_hdr.values()))) - # CKSUM is calculated after "CKSUM" field - hdr_cksum = self.ldr_2nd_hdr["CKSUM"] - crc = self.image_crc((hdr + body)[hdr_cksum.end :]) - hdr_cksum.content = crc - hdr = bytearray(b"".join((e.content for e in self.ldr_2nd_hdr.values()))) - - self.body2["LOADER_2ND"].content = hdr + body - - def _compress_ldr_2nd(self): - image = self.body2["LOADER_2ND"].content - hdr_size = self._param_size(self.ldr_2nd_hdr) - hdr, body = image[:hdr_size], image[hdr_size:] - - magic = self.ldr_2nd_hdr["MAGIC"].content - if magic == LOADER_2ND_MAGIC_ORIG: - # if image is uncompressed, compress it. - if self.compress_algo is None: - pass - elif self.compress_algo == "lzma": - self.ldr_2nd_hdr["MAGIC"].content = LOADER_2ND_MAGIC_LZMA - body = lzma_compress(body) - logging.info("lzma loader_2nd=%#x bytes wo header", len(body)) - elif self.compress_algo == "lz4": - self.ldr_2nd_hdr["MAGIC"].content = LOADER_2ND_MAGIC_LZ4 - body = lz4_compress(body) - logging.info("lz4 loader_2nd=%#x bytes wo header", len(body)) - else: - raise NotImplementedError("'%r' is not supported." % self.compress_algo) - elif magic in LOADER_2ND_MAGIC_LIST: - logging.info("loader_2nd is already compressed") - else: - raise ValueError("unknown loader_2nd magic (%r)", magic) - - self.body2["LOADER_2ND"].content = self.pad(hdr + body, IMAGE_ALIGN) - - def pack_loader_2nd(self, fip_bin): - logging.debug("pack_loader_2nd:") - if not len(self.body2["LOADER_2ND"].content): - return - - fip_bin = self.pad(fip_bin, IMAGE_ALIGN) - self.param2["LOADER_2ND_LOADADDR"].content = len(fip_bin) - - self._parse_ldr_2nd_hdr(self.body2["LOADER_2ND"].content) - self._compress_ldr_2nd() - self._update_ldr_2nd_hdr() - - # Append LOADER_2ND to body2 - return fip_bin + self.body2["LOADER_2ND"].content - - def insert_param1(self, fip_bin, name, value): - fip_bin = bytearray(fip_bin) - e = self.param1[name] - e.content = value - fip_bin[e.addr : e.end] = value - return self.update_param1_cksum(fip_bin) - - def append_fip2(self, fip1_bin, args): - logging.debug("make_fip2:") - fip_bin = bytearray(fip1_bin) - - # Update PARAM2_LOADADDR - param2_loadaddr = len(fip1_bin) - fip_bin = self.insert_param1(fip_bin, "PARAM2_LOADADDR", pack("<I", param2_loadaddr)) - - # Add an empty PARAM2 - fip_bin += b"\0" * PARAM2_SIZE - - # Pack body - fip_bin = self.pack_ddr_param(fip_bin) - - if len(self.body2["BLCP_2ND"].content): - runaddr = self.param2["BLCP_2ND_RUNADDR"].toint() - if not runaddr: - runaddr = int(args.BLCP_2ND_RUNADDR) - fip_bin = self.pack_blcp_2nd(fip_bin, runaddr) - - if len(self.body2["MONITOR"].content): - runaddr = self.param2["MONITOR_RUNADDR"].toint() - if not runaddr: - runaddr = int(args.MONITOR_RUNADDR) - fip_bin = self.pack_monitor(fip_bin, runaddr) - - if len(self.body2["LOADER_2ND"].content): - fip_bin = self.pack_loader_2nd(fip_bin) - - # Pack param2_bin - param2_bin = b"".join((entry.content for entry in self.param2.values())) - self.param2["PARAM2_CKSUM"].content = self.image_crc(param2_bin[self.param2["PARAM2_CKSUM"].end :]) - param2_bin = b"".join((entry.content for entry in self.param2.values())) # update cksum - - logging.debug("len(param2_bin) is %d", len(param2_bin)) - assert len(param2_bin) == PARAM2_SIZE - - fip_bin[param2_loadaddr : param2_loadaddr + PARAM2_SIZE] = param2_bin - - return fip_bin - - def make(self, args=None): - fip_bin = self.make_fip1() - if len(self.body2["DDR_PARAM"].content): - fip_bin = self.append_fip2(fip_bin, args) - - logging.info("generated fip_bin is %d bytes", len(fip_bin)) - - if getattr(self, "rest_fip", None): - logging.error("the rest of fip is not used: %#x bytes ", len(self.rest_fip)) - - return fip_bin - - -METHODS = { - "NOR_INFO": FIP.add_nor_info, - "NAND_INFO": FIP.add_nand_info, - "CHIP_CONF": FIP.add_chip_conf, - "BLCP": FIP.add_blcp, - "BL2": FIP.add_bl2, - "DDR_PARAM": FIP.add_ddr_param, - "BLCP_2ND": FIP.add_blcp_2nd, - "MONITOR": FIP.add_monitor, - "LOADER_2ND": FIP.add_loader_2nd, -} - - -def generate_fip(args): - logging.debug("generate_fip:") - fip = FIP() - - if args.OLD_FIP: - fip.read_fip(args.OLD_FIP) - - for m, f in METHODS.items(): - if getattr(args, m): - f(fip, args) - - fip_bin = fip.make(args) - fip.print_fip_params() - - if args.output: - with open(args.output, "wb") as fp: - fp.write(fip_bin) - - -def parse_args(): - parser = argparse.ArgumentParser(description="FIP tools") - - parser.add_argument( - "-v", - "--verbose", - help="Increase output verbosity", - action="store_const", - const=logging.DEBUG, - default=logging.INFO, - ) - - subparsers = parser.add_subparsers(dest="subcmd", help="Sub-command help") - pr_gen = subparsers.add_parser("genfip", help="Generate keys") - - for name in list(METHODS): - if name in ["NOR_INFO", "NAND_INFO"]: - pr_gen.add_argument("--" + name, type=bytes.fromhex) - else: - pr_gen.add_argument("--" + name, dest=name, type=str, help="Add %s into FIP" % name) - - def auto_int(x): - return int(x, 0) - - pr_gen.add_argument("--BLCP_IMG_RUNADDR", type=auto_int) - pr_gen.add_argument("--BLCP_PARAM_LOADADDR", type=auto_int) - - pr_gen.add_argument("--BLCP_2ND_RUNADDR", type=auto_int) - - pr_gen.add_argument("--MONITOR_RUNADDR", type=auto_int) - - pr_gen.add_argument("--compress", choices=["lzma", "lz4", ""]) - - pr_gen.add_argument("--OLD_FIP", type=str) - pr_gen.add_argument("--BLOCK_SIZE", type=auto_int) - pr_gen.add_argument("--BL2_FILL", type=auto_int) - - pr_gen.add_argument("output", type=str, help="Output filename") - - pr_gen.set_defaults(func=generate_fip) - - if argcomplete: - argcomplete.autocomplete(parser) - - args = parser.parse_args() - init_logging(stdout_level=args.verbose) - logging.info("PROG: %s", parser.prog) - - if not args.subcmd: - parser.print_help() - raise SystemExit(1) - - for a, v in sorted(vars(args).items()): - logging.debug(" %s=%r", a, v) - - return args - - -def main(): - args = parse_args() - args.func(args) - - -def init_logging(log_file=None, file_level="DEBUG", stdout_level="WARNING"): - root_logger = logging.getLogger() - root_logger.setLevel(logging.NOTSET) - - fmt = "%(asctime)s %(levelname)8s:%(name)s:%(message)s" - - if log_file is not None: - file_handler = logging.FileHandler(log_file, encoding="utf-8") - file_handler.setFormatter(logging.Formatter(fmt)) - file_handler.setLevel(file_level) - root_logger.addHandler(file_handler) - - if coloredlogs: - os.environ["COLOREDLOGS_DATE_FORMAT"] = "%H:%M:%S" - - field_styles = { - "asctime": {"color": "green"}, - "hostname": {"color": "magenta"}, - "levelname": {"color": "black", "bold": True}, - "name": {"color": "blue"}, - "programname": {"color": "cyan"}, - } - - level_styles = coloredlogs.DEFAULT_LEVEL_STYLES - level_styles["debug"]["color"] = "cyan" - - coloredlogs.install( - level=stdout_level, - fmt=fmt, - field_styles=field_styles, - level_styles=level_styles, - milliseconds=True, - ) - - -if __name__ == "__main__": - main() diff --git a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/u-boot-raw.bin b/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/u-boot-raw.bin Binary files differdeleted file mode 100644 index 48e69e41eb..0000000000 --- a/bsp/cvitek/cv18xx_aarch64/prebuild/duo256m/u-boot-raw.bin +++ /dev/null diff --git a/bsp/cvitek/cv18xx_aarch64/rtconfig.py b/bsp/cvitek/cv18xx_aarch64/rtconfig.py index 16f5706bb7..1830e216dc 100644 --- a/bsp/cvitek/cv18xx_aarch64/rtconfig.py +++ b/bsp/cvitek/cv18xx_aarch64/rtconfig.py @@ -46,4 +46,4 @@ if PLATFORM == 'gcc': DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' POST_ACTION += OBJCPY + ' -O binary $TARGET Image \n' + SIZE + ' $TARGET \n' -POST_ACTION += './combine.sh && ./mksdimg.sh ' + os.getcwd() + ' Image \n' +POST_ACTION += 'cd .. && ./build.sh -a \n' |
