[bsp/cvitek] Update packaging method
Use pre-build files to reduce compilation time Signed-off-by: flyingcys <flyingcys@163.com>
This commit is contained in:
parent
87906499a3
commit
7df04a07a4
|
@ -1,44 +1,28 @@
|
|||
#!/bin/bash
|
||||
|
||||
function get_board_type()
|
||||
function check_board()
|
||||
{
|
||||
BOARD_CONFIG=("CONFIG_BOARD_TYPE_MILKV_DUO" "CONFIG_BOARD_TYPE_MILKV_DUO_SPINOR" "CONFIG_BOARD_TYPE_MILKV_DUO_SPINAND" "CONFIG_BOARD_TYPE_MILKV_DUO256M" "CONFIG_BOARD_TYPE_MILKV_DUO256M_SPINOR" "CONFIG_BOARD_TYPE_MILKV_DUO256M_SPINAND" "CONFIG_BOARD_TYPE_MILKV_DUOS")
|
||||
BOARD_VALUE=("milkv-duo" "milkv-duo-spinor" "milkv-duo-spinand" "milkv-duo256m" "milkv-duo256m-spinor" "milkv-duo256m-spinand" "milkv-duos-sd")
|
||||
STORAGE_VAUE=("sd" "spinor" "spinand" "sd" "spinor" "spinand" "sd")
|
||||
local config_file=$1/.config
|
||||
|
||||
for ((i=0;i<${#BOARD_CONFIG[@]};i++))
|
||||
do
|
||||
config_value=$(grep -w "${BOARD_CONFIG[i]}" ${PROJECT_PATH}/.config | cut -d= -f2)
|
||||
if [ "$config_value" == "y" ]; then
|
||||
BOARD_TYPE=${BOARD_VALUE[i]}
|
||||
STORAGE_TYPE=${STORAGE_VAUE[i]}
|
||||
break
|
||||
fi
|
||||
done
|
||||
export BOARD_TYPE=${BOARD_TYPE}
|
||||
export STORAGE_TYPE=${STORAGE_TYPE}
|
||||
}
|
||||
board_type=$(grep -E '^CONFIG_BOARD_TYPE_.*=y' "$config_file" | sed 's/CONFIG_BOARD_TYPE_//;s/=y$//')
|
||||
|
||||
function check_bootloader()
|
||||
{
|
||||
restult=$(curl -m 10 -s http://www.ip-api.com/json)
|
||||
COUNTRY=$(echo $restult | sed 's/.*"country":"\([^"]*\)".*/\1/')
|
||||
echo "Country: $COUNTRY"
|
||||
|
||||
if [ "$COUNTRY" == "China" ]; then
|
||||
BOOTLOADER_URL=https://gitee.com/flyingcys/cvitek_bootloader
|
||||
else
|
||||
BOOTLOADER_URL=https://github.com/flyingcys/cvitek_bootloader
|
||||
if [ -z "$board_type" ]; then
|
||||
echo "No board type found in the config file."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -d cvitek_bootloader ]; then
|
||||
echo "cvitek_bootloader not exist, clone it from ${BOOTLOADER_URL}"
|
||||
git clone ${BOOTLOADER_URL}
|
||||
BOARD_TYPE=$(echo "$board_type" | tr '[:upper:]' '[:lower:]')
|
||||
STORAGE_TYPE="${BOARD_TYPE##*_}"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to clone ${BOOTLOADER_URL} !"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
soc_type=$(grep -E '^CONFIG_SOC_TYPE_.*=y' "$config_file" | sed 's/CONFIG_SOC_TYPE_//;s/=y$//')
|
||||
if [ -z "$soc_type" ]; then
|
||||
echo "No soc type found in the config file."
|
||||
return 1
|
||||
fi
|
||||
|
||||
SOC_TYPE=$(echo "$soc_type" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
export BOARD_TYPE STORAGE_TYPE SOC_TYPE
|
||||
|
||||
return 0
|
||||
}
|
|
@ -95,6 +95,7 @@ CONFIG_ARCH_RISCV=y
|
|||
CONFIG_ARCH_RISCV_FPU=y
|
||||
CONFIG_ARCH_RISCV_FPU_D=y
|
||||
CONFIG_ARCH_RISCV64=y
|
||||
CONFIG_ARCH_USING_NEW_CTX_SWITCH=y
|
||||
|
||||
#
|
||||
# RT-Thread Components
|
||||
|
@ -934,6 +935,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
|
|||
# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
|
||||
|
@ -1175,6 +1177,7 @@ CONFIG_BSP_UART_IRQ_BASE=30
|
|||
# CONFIG_BSP_USING_ADC is not set
|
||||
# CONFIG_BSP_USING_SPI is not set
|
||||
# CONFIG_BSP_USING_WDT is not set
|
||||
# CONFIG_BSP_USING_TIMER is not set
|
||||
# CONFIG_BSP_USING_PWM is not set
|
||||
# CONFIG_BSP_USING_RTC is not set
|
||||
# end of General Drivers Configuration
|
||||
|
@ -1186,7 +1189,8 @@ CONFIG_BSP_TIMER_CLK_FREQ=25000000
|
|||
CONFIG_BSP_GPIO_IRQ_BASE=41
|
||||
CONFIG_BSP_SYS_GPIO_IRQ_BASE=47
|
||||
CONFIG_SOC_TYPE_SG2002=y
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO_SD is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO_SPINOR is not set
|
||||
CONFIG_BOARD_TYPE_MILKV_DUO256M=y
|
||||
CONFIG_BOARD_TYPE_MILKV_DUO256M_SD=y
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO256M_SPINOR is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUOS_SD is not set
|
||||
|
|
|
@ -52,26 +52,26 @@ config SOC_TYPE_SG2002
|
|||
|
||||
choice
|
||||
prompt "Board Type"
|
||||
default BOARD_TYPE_MILKV_DUO256M
|
||||
default BOARD_TYPE_MILKV_DUO256M_SD
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO
|
||||
config BOARD_TYPE_MILKV_DUO_SD
|
||||
select SOC_TYPE_CV180X
|
||||
bool "milkv-duo"
|
||||
bool "milkv-duo-sd"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO_SPINOR
|
||||
select SOC_TYPE_CV180X
|
||||
bool "milkv-duo-spinor"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M
|
||||
config BOARD_TYPE_MILKV_DUO256M_SD
|
||||
select SOC_TYPE_SG2002
|
||||
bool "milkv-duo256m"
|
||||
bool "milkv-duo256m-sd"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M_SPINOR
|
||||
select SOC_TYPE_SG2002
|
||||
bool "milkv-duo256m-spinor"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUOS
|
||||
config BOARD_TYPE_MILKV_DUOS_SD
|
||||
select SOC_TYPE_SG2000
|
||||
bool "milkv-duos"
|
||||
bool "milkv-duos-sd"
|
||||
|
||||
endchoice
|
||||
|
|
|
@ -34,7 +34,7 @@ objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
|
|||
# include libraries
|
||||
objs.extend(SConscript(drivers_path_prefix + '/SConscript', variant_dir='build/drivers', duplicate=0))
|
||||
|
||||
if GetDepend('BOARD_TYPE_MILKV_DUO256M') or GetDepend('BOARD_TYPE_MILKV_DUOS'):
|
||||
if GetDepend('BOARD_TYPE_MILKV_DUO256M_SD') or GetDepend('BOARD_TYPE_MILKV_DUOS_SD'):
|
||||
env['LINKFLAGS'] = env['LINKFLAGS'].replace('cv180x_lscript.ld', 'cv181x_lscript.ld')
|
||||
env['LINKFLAGS'] = env['LINKFLAGS'].replace('-L board/script/cv180x', '-L board/script/cv181x')
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#define ARCH_RISCV_FPU
|
||||
#define ARCH_RISCV_FPU_D
|
||||
#define ARCH_RISCV64
|
||||
#define ARCH_USING_NEW_CTX_SWITCH
|
||||
|
||||
/* RT-Thread Components */
|
||||
|
||||
|
@ -335,6 +336,6 @@
|
|||
#define BSP_GPIO_IRQ_BASE 41
|
||||
#define BSP_SYS_GPIO_IRQ_BASE 47
|
||||
#define SOC_TYPE_SG2002
|
||||
#define BOARD_TYPE_MILKV_DUO256M
|
||||
#define BOARD_TYPE_MILKV_DUO256M_SD
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PROJECT_PATH=$1
|
||||
IMAGE_NAME=$2
|
||||
|
@ -8,42 +9,64 @@ if [ -z "$PROJECT_PATH" ] || [ -z "$IMAGE_NAME" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
function do_combine()
|
||||
{
|
||||
local PROJECT_PATH=$1
|
||||
local IMAGE_NAME=$2
|
||||
|
||||
BLCP_IMG_RUNADDR=0x05200200
|
||||
BLCP_PARAM_LOADADDR=0
|
||||
NAND_INFO=00000000
|
||||
NOR_INFO='FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
|
||||
FIP_COMPRESS=lzma
|
||||
|
||||
BUILD_PLAT=${ROOT_PATH}/pre-build/fsbl/build/${SOC_TYPE}
|
||||
|
||||
CHIP_CONF_PATH=${BUILD_PLAT}/chip_conf.bin
|
||||
DDR_PARAM_TEST_PATH=${ROOT_PATH}/pre-build/fsbl/test/ddr_param.bin
|
||||
BLCP_PATH=${ROOT_PATH}/pre-build/fsbl/test/empty.bin
|
||||
|
||||
MONITOR_PATH=${ROOT_PATH}/pre-build/opensbi/${BOARD_TYPE}/fw_dynamic.bin
|
||||
LOADER_2ND_PATH=${ROOT_PATH}/pre-build/u-boot-2021.10/${BOARD_TYPE}/u-boot-raw.bin
|
||||
|
||||
BLCP_2ND_PATH=$PROJECT_PATH/$IMAGE_NAME
|
||||
|
||||
echo "Combining fip.bin..."
|
||||
. ./pre-build/fsbl/build/${SOC_TYPE}/blmacros.env && \
|
||||
python3 ./pre-build/fsbl/plat/fiptool.py -v genfip \
|
||||
${ROOT_PATH}/output/${BOARD_TYPE}/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}
|
||||
}
|
||||
|
||||
ROOT_PATH=$(pwd)
|
||||
echo $ROOT_PATH
|
||||
|
||||
. board_env.sh
|
||||
|
||||
get_board_type
|
||||
echo "board_type: ${BOARD_TYPE}"
|
||||
|
||||
check_bootloader || exit 0
|
||||
|
||||
export BLCP_2ND_PATH=${PROJECT_PATH}/${IMAGE_NAME}
|
||||
|
||||
pushd cvitek_bootloader
|
||||
|
||||
. env.sh
|
||||
|
||||
get_build_board ${BOARD_TYPE}
|
||||
|
||||
echo "board: ${MV_BOARD_LINK}"
|
||||
|
||||
if [ ! -d opensbi/build/platform/generic ] || [ ! -d fsbl/build/${MV_BOARD_LINK} ] || [ ! -d u-boot-2021.10/build/${MV_BOARD_LINK} ]; then
|
||||
do_build
|
||||
|
||||
CHIP_ARCH_L=$(echo $CHIP_ARCH | tr '[:upper:]' '[:lower:]')
|
||||
cp -rf build/output/${MV_BOARD_LINK}/cvi_board_memmap.ld ${ROOT_PATH}/c906_little/board/script/${CHIP_ARCH_L}
|
||||
if check_board ${PROJECT_PATH} ; then
|
||||
echo "board type: ${BOARD_TYPE}"
|
||||
echo "storage type: ${STORAGE_TYPE}"
|
||||
else
|
||||
echo "Build already done, skip build"
|
||||
|
||||
do_combine
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
do_build
|
||||
fi
|
||||
echo "board type not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
popd
|
||||
mkdir -p output/${BOARD_TYPE}
|
||||
do_combine $PROJECT_PATH $IMAGE_NAME
|
||||
|
||||
echo "=== Done fip combine for ${BOARD_TYPE} successfully! ==="
|
||||
|
||||
mkdir -p output/${MV_BOARD}
|
||||
cp -rf cvitek_bootloader/install/soc_${MV_BOARD_LINK}/fip.bin output/${MV_BOARD}/fip.bin
|
||||
exit 0
|
|
@ -36,11 +36,11 @@ config SOC_TYPE_SG2002
|
|||
|
||||
choice
|
||||
prompt "Board Type"
|
||||
default BOARD_TYPE_MILKV_DUO256M
|
||||
default BOARD_TYPE_MILKV_DUO256M_SD
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M
|
||||
config BOARD_TYPE_MILKV_DUO256M_SD
|
||||
select SOC_TYPE_SG2002
|
||||
bool "milkv-duo256m"
|
||||
bool "milkv-duo256m-sd"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M_SPINOR
|
||||
select SOC_TYPE_SG2002
|
||||
|
|
|
@ -99,6 +99,7 @@ CONFIG_ARCH_RISCV=y
|
|||
CONFIG_ARCH_RISCV_FPU=y
|
||||
CONFIG_ARCH_RISCV_FPU_D=y
|
||||
CONFIG_ARCH_RISCV64=y
|
||||
CONFIG_ARCH_USING_NEW_CTX_SWITCH=y
|
||||
CONFIG_ARCH_USING_RISCV_COMMON64=y
|
||||
|
||||
#
|
||||
|
@ -431,6 +432,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_WEBTERMINAL is not set
|
||||
# CONFIG_PKG_USING_FREEMODBUS is not set
|
||||
# CONFIG_PKG_USING_NANOPB is not set
|
||||
# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set
|
||||
|
||||
#
|
||||
# Wi-Fi
|
||||
|
@ -535,6 +537,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_ZEPHYR_POLLING is not set
|
||||
# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set
|
||||
# CONFIG_PKG_USING_LHC_MODBUS is not set
|
||||
# CONFIG_PKG_USING_QMODBUS is not set
|
||||
# end of IoT - internet of things
|
||||
|
||||
#
|
||||
|
@ -562,6 +565,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_JSMN is not set
|
||||
# CONFIG_PKG_USING_AGILE_JSMN is not set
|
||||
# CONFIG_PKG_USING_PARSON is not set
|
||||
# CONFIG_PKG_USING_RYAN_JSON is not set
|
||||
# end of JSON: JavaScript Object Notation, a lightweight data-interchange format
|
||||
|
||||
#
|
||||
|
@ -680,6 +684,8 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
|
||||
# end of enhanced kernel services
|
||||
|
||||
# CONFIG_PKG_USING_AUNITY is not set
|
||||
|
||||
#
|
||||
# acceleration: Assembly language or algorithmic acceleration packages
|
||||
#
|
||||
|
@ -770,11 +776,29 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
#
|
||||
# STM32 HAL & SDK Drivers
|
||||
#
|
||||
# CONFIG_PKG_USING_STM32L4XX_HAL_DRIVER is not set
|
||||
# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set
|
||||
# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set
|
||||
# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set
|
||||
# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set
|
||||
# CONFIG_PKG_USING_STM32WB55_SDK is not set
|
||||
# CONFIG_PKG_USING_STM32_SDIO is not set
|
||||
# end of STM32 HAL & SDK Drivers
|
||||
|
||||
#
|
||||
# Infineon HAL Packages
|
||||
#
|
||||
# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set
|
||||
# CONFIG_PKG_USING_INFINEON_CMSIS is not set
|
||||
# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set
|
||||
# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set
|
||||
# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set
|
||||
# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set
|
||||
# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set
|
||||
# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set
|
||||
# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set
|
||||
# CONFIG_PKG_USING_INFINEON_USBDEV is not set
|
||||
# end of Infineon HAL Packages
|
||||
|
||||
# CONFIG_PKG_USING_BLUETRUM_SDK is not set
|
||||
# CONFIG_PKG_USING_EMBARC_BSP is not set
|
||||
# CONFIG_PKG_USING_ESP_IDF is not set
|
||||
|
@ -948,6 +972,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set
|
||||
# CONFIG_PKG_USING_BT_MX01 is not set
|
||||
# CONFIG_PKG_USING_RGPOWER is not set
|
||||
# CONFIG_PKG_USING_BT_MX02 is not set
|
||||
# CONFIG_PKG_USING_SPI_TOOLS is not set
|
||||
# end of peripheral libraries and drivers
|
||||
|
||||
|
@ -969,6 +994,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
#
|
||||
# Signal Processing and Control Algorithm Packages
|
||||
#
|
||||
# CONFIG_PKG_USING_APID is not set
|
||||
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
|
||||
# CONFIG_PKG_USING_QPID is not set
|
||||
# CONFIG_PKG_USING_UKAL is not set
|
||||
|
@ -1056,6 +1082,7 @@ CONFIG_RT_USING_ADT_REF=y
|
|||
# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
|
||||
# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
|
||||
|
@ -1297,6 +1324,7 @@ CONFIG_BSP_UART_IRQ_BASE=44
|
|||
# CONFIG_BSP_USING_ADC is not set
|
||||
# CONFIG_BSP_USING_SPI is not set
|
||||
# CONFIG_BSP_USING_WDT is not set
|
||||
# CONFIG_BSP_USING_TIMER is not set
|
||||
# CONFIG_BSP_USING_PWM is not set
|
||||
# CONFIG_BSP_USING_RTC is not set
|
||||
# CONFIG_BSP_USING_SDH is not set
|
||||
|
@ -1310,9 +1338,10 @@ CONFIG_BSP_GPIO_IRQ_BASE=60
|
|||
CONFIG_BSP_SYS_GPIO_IRQ_BASE=70
|
||||
CONFIG___STACKSIZE__=8192
|
||||
CONFIG_SOC_TYPE_SG2002=y
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO_SD is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO_SPINOR is not set
|
||||
CONFIG_BOARD_TYPE_MILKV_DUO256M=y
|
||||
CONFIG_BOARD_TYPE_MILKV_DUO256M_SD=y
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUO256M_SPINOR is not set
|
||||
# CONFIG_BOARD_TYPE_MILKV_DUOS_SD is not set
|
||||
CONFIG_BSP_ROOTFS_TYPE_ROMFS=y
|
||||
# CONFIG_BSP_ROOTFS_TYPE_CROMFS is not set
|
||||
|
|
|
@ -58,27 +58,27 @@ config SOC_TYPE_SG2002
|
|||
|
||||
choice
|
||||
prompt "Board Type"
|
||||
default BOARD_TYPE_MILKV_DUO256M
|
||||
default BOARD_TYPE_MILKV_DUO256M_SD
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO
|
||||
config BOARD_TYPE_MILKV_DUO_SD
|
||||
select SOC_TYPE_CV180X
|
||||
bool "milkv-duo"
|
||||
bool "milkv-duo-sd"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO_SPINOR
|
||||
select SOC_TYPE_CV180X
|
||||
bool "milkv-duo-spinor"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M
|
||||
config BOARD_TYPE_MILKV_DUO256M_SD
|
||||
select SOC_TYPE_SG2002
|
||||
bool "milkv-duo256m"
|
||||
bool "milkv-duo256m-sd"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUO256M_SPINOR
|
||||
select SOC_TYPE_SG2002
|
||||
bool "milkv-duo256m-spinor"
|
||||
|
||||
config BOARD_TYPE_MILKV_DUOS
|
||||
config BOARD_TYPE_MILKV_DUOS_SD
|
||||
select SOC_TYPE_SG2000
|
||||
bool "milkv-duos"
|
||||
bool "milkv-duos-sd"
|
||||
|
||||
endchoice
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#include <stdio.h>
|
||||
#include <drivers/dev_pin.h>
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#define LED_PIN "E02" /* Onboard LED pins */
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#define LED_PIN "C24" /* Onboard LED pins */
|
||||
#elif defined(BOARD_TYPE_MILKV_DUOS)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUOS_SD)
|
||||
#define LED_PIN "A29" /* Onboard LED pins */
|
||||
#endif
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -68,6 +68,7 @@
|
|||
#define ARCH_RISCV_FPU
|
||||
#define ARCH_RISCV_FPU_D
|
||||
#define ARCH_RISCV64
|
||||
#define ARCH_USING_NEW_CTX_SWITCH
|
||||
#define ARCH_USING_RISCV_COMMON64
|
||||
|
||||
/* RT-Thread Components */
|
||||
|
@ -357,6 +358,10 @@
|
|||
|
||||
/* end of STM32 HAL & SDK Drivers */
|
||||
|
||||
/* Infineon HAL Packages */
|
||||
|
||||
/* end of Infineon HAL Packages */
|
||||
|
||||
/* Kendryte SDK */
|
||||
|
||||
/* end of Kendryte SDK */
|
||||
|
@ -455,7 +460,7 @@
|
|||
#define BSP_SYS_GPIO_IRQ_BASE 70
|
||||
#define __STACKSIZE__ 8192
|
||||
#define SOC_TYPE_SG2002
|
||||
#define BOARD_TYPE_MILKV_DUO256M
|
||||
#define BOARD_TYPE_MILKV_DUO256M_SD
|
||||
#define BSP_ROOTFS_TYPE_ROMFS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,9 +12,9 @@ CPPDEFINES = []
|
|||
CPPPATH = [cwd]
|
||||
|
||||
CHIP_TYPE = 'cv180x'
|
||||
if GetDepend('BOARD_TYPE_MILKV_DUO256M') or GetDepend('BOARD_TYPE_MILKV_DUO256M_SPINOR') or GetDepend('BOARD_TYPE_MILKV_DUO256M_SPINAND') or GetDepend('BOARD_TYPE_MILKV_DUOS'):
|
||||
if GetDepend('SOC_TYPE_SG2002') or GetDepend('SOC_TYPE_SG2000'):
|
||||
CHIP_TYPE = 'cv181x'
|
||||
elif GetDepend('BOARD_TYPE_MILKV_DUO') or GetDepend('BOARD_TYPE_MILKV_DUO_SPINOR') or GetDepend('BOARD_TYPE_MILKV_DUO_SPINAND'):
|
||||
elif GetDepend('SOC_TYPE_CV180X'):
|
||||
CHIP_TYPE = 'cv180x'
|
||||
|
||||
CPPPATH += [cwd + r'/libraries']
|
||||
|
|
|
@ -153,7 +153,7 @@ static const struct rt_adc_ops _adc_ops =
|
|||
};
|
||||
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
|
||||
/*
|
||||
* cv180xb supports
|
||||
|
@ -188,7 +188,7 @@ static const char *pinname_whitelist_adc3_nodie[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
|
||||
/*
|
||||
* sg2002 supports
|
||||
|
|
|
@ -427,7 +427,7 @@ static void dw_iic_init(dw_iic_regs_t *iic_base)
|
|||
dw_iic_set_standard_scl_lcnt(iic_base, (((IC_CLK * 4700) / 1000U) - 1U));
|
||||
}
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_I2C0
|
||||
static const char *pinname_whitelist_i2c0_scl[] = {
|
||||
|
@ -486,7 +486,7 @@ static const char *pinname_whitelist_i2c4_sda[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_I2C0
|
||||
// I2C0 is not ALLOWED for Duo256
|
||||
|
|
|
@ -136,7 +136,7 @@ static struct cvi_pwm_dev cvi_pwm[] =
|
|||
};
|
||||
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_PWM0
|
||||
static const char *pinname_whitelist_pwm0[] = {
|
||||
|
@ -208,7 +208,7 @@ static const char *pinname_whitelist_pwm15[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_PWM0
|
||||
static const char *pinname_whitelist_pwm0[] = {
|
||||
|
|
|
@ -224,7 +224,7 @@ static const struct rt_spi_ops _spi_ops =
|
|||
.xfer = spi_xfer,
|
||||
};
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR) || defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR) || defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
// For Duo / Duo 256m, only SPI2 are exported on board.
|
||||
#ifdef BSP_USING_SPI0
|
||||
static const char *pinname_whitelist_spi0_sck[] = {
|
||||
|
|
|
@ -239,7 +239,7 @@ static void rt_hw_uart_isr(int irqno, void *param)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(BOARD_TYPE_MILKV_DUO) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
#if defined(BOARD_TYPE_MILKV_DUO_SD) || defined(BOARD_TYPE_MILKV_DUO_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
static const char *pinname_whitelist_uart0_rx[] = {
|
||||
|
@ -300,7 +300,7 @@ static const char *pinname_whitelist_uart4_tx[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUO256M_SD) || defined(BOARD_TYPE_MILKV_DUO256M_SPINOR)
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
static const char *pinname_whitelist_uart0_rx[] = {
|
||||
|
@ -361,7 +361,7 @@ static const char *pinname_whitelist_uart4_tx[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#elif defined(BOARD_TYPE_MILKV_DUOS)
|
||||
#elif defined(BOARD_TYPE_MILKV_DUOS_SD)
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
static const char *pinname_whitelist_uart0_rx[] = {
|
||||
|
|
|
@ -14,31 +14,26 @@ echo ${ROOT_PATH}
|
|||
|
||||
. board_env.sh
|
||||
|
||||
get_board_type
|
||||
|
||||
echo "start compress kernel..."
|
||||
|
||||
if check_board ${PROJECT_PATH} ; then
|
||||
echo "board type: ${BOARD_TYPE}"
|
||||
echo "storage type: ${STORAGE_TYPE}"
|
||||
else
|
||||
echo "board type not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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.${STORAGE_TYPE}
|
||||
./pre-build/tools/mkimage -f ${PROJECT_PATH}/dtb/${BOARD_TYPE}/multi.its -r ${ROOT_PATH}/output/${BOARD_TYPE}/boot.${STORAGE_TYPE}
|
||||
|
||||
if [ "${STORAGE_TYPE}" == "spinor" ] || [ "${STORAGE_TYPE}" == "spinand" ]; then
|
||||
|
||||
check_bootloader || exit 0
|
||||
|
||||
pushd cvitek_bootloader
|
||||
|
||||
. env.sh
|
||||
get_build_board ${BOARD_TYPE}
|
||||
|
||||
CHIP_ARCH_L=$(echo $CHIP_ARCH | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
echo "board: ${MV_BOARD_LINK}"
|
||||
|
||||
IMGTOOL_PATH=build/tools/common/image_tool
|
||||
FLASH_PARTITION_XML=build/boards/"${CHIP_ARCH_L}"/"${MV_BOARD_LINK}"/partition/partition_"${STORAGE_TYPE}".xml
|
||||
IMGTOOL_PATH=${ROOT_PATH}/pre-build/tools/common/image_tool
|
||||
FLASH_PARTITION_XML=${ROOT_PATH}/pre-build/boards/${BOARD_TYPE}/partition/partition_"${STORAGE_TYPE}".xml
|
||||
python3 "$IMGTOOL_PATH"/raw2cimg.py "${ROOT_PATH}"/output/"${BOARD_TYPE}"/boot."$STORAGE_TYPE" "${ROOT_PATH}/output/${BOARD_TYPE}" "$FLASH_PARTITION_XML"
|
||||
|
||||
popd
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1 @@
|
|||
tools/common/image_tool/__pycache__
|
|
@ -0,0 +1,12 @@
|
|||
<physical_partition type="spinand">
|
||||
<partition label="fip" size_in_kb="2560" file="fip.bin"/>
|
||||
<partition label="BOOT" size_in_kb="4096" file="boot.spinand"/>
|
||||
<partition label="MISC" size_in_kb="384" file="logo.jpg" />
|
||||
<partition label="ENV" size_in_kb="128" file="" />
|
||||
<partition label="ENV_BAK" size_in_kb="128" file="" />
|
||||
<partition label="ROOTFS" size_in_kb="71680" file="rootfs.spinand" />
|
||||
<partition label="SYSTEM" size_in_kb="20480" file="system.spinand" mountpoint="" type="ubifs" />
|
||||
<partition label="CFG" size_in_kb="4096" file="cfg.spinand" mountpoint="/mnt/cfg" type="ubifs" />
|
||||
<partition label="DATA" file="" mountpoint="/mnt/data" type="ubifs" />
|
||||
</physical_partition>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<physical_partition type="spinor">
|
||||
<partition label="fip" size_in_kb="1024" readonly="false" file="fip.bin"/>
|
||||
<partition label="BOOT" size_in_kb="3072" readonly="false" file="boot.spinor"/>
|
||||
<partition label="ENV" size_in_kb="64" file="" />
|
||||
<partition label="ENV_BAK" size_in_kb="64" file="" />
|
||||
<partition label="ROOTFS" size_in_kb="10240" readonly="false" file="rootfs.spinor" />
|
||||
<partition label="DATA" size_in_kb="512" readonly="false" file="data.spinor" mountpoint="/mnt/data" type="jffs2" />
|
||||
</physical_partition>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<physical_partition type="spinand">
|
||||
<partition label="fip" size_in_kb="2560" file="fip.bin"/>
|
||||
<partition label="BOOT" size_in_kb="6144" file="boot.spinand"/>
|
||||
<partition label="ENV" size_in_kb="128" file="" />
|
||||
<partition label="ENV_BAK" size_in_kb="128" file="" />
|
||||
<partition label="ROOTFS" size_in_kb="40960" file="rootfs.spinand" />
|
||||
<partition label="SYSTEM" size_in_kb="81152" file="system.spinand" mountpoint="/mnt/system" type="ubifs" />
|
||||
</physical_partition>
|
|
@ -0,0 +1,7 @@
|
|||
<physical_partition type="spinor">
|
||||
<partition label="fip" size_in_kb="640" readonly="false" file="fip.bin"/>
|
||||
<partition label="BOOT" size_in_kb="4096" readonly="false" file="boot.spinor"/>
|
||||
<partition label="ENV" size_in_kb="64" file="" />
|
||||
<partition label="ROOTFS" size_in_kb="27968" readonly="true" file="rootfs.spinor" />
|
||||
</physical_partition>
|
||||
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
MONITOR_RUNADDR=0x0000000080000000
|
||||
BLCP_2ND_RUNADDR=0x0000000083f40000
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
MONITOR_RUNADDR=0x0000000080000000
|
||||
BLCP_2ND_RUNADDR=0x000000009fe00000
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
MONITOR_RUNADDR=0x0000000080000000
|
||||
BLCP_2ND_RUNADDR=0x000000008fe00000
|
Binary file not shown.
|
@ -0,0 +1,802 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
FORMAT = "%(levelname)s: %(message)s"
|
||||
logging.basicConfig(level=logging.INFO, format=FORMAT)
|
||||
Storage_EMMC = 0
|
||||
Storage_SPINAND = 1
|
||||
Storage_SPINOR = 2
|
||||
LBA_SIZE = 512
|
||||
|
||||
|
||||
class XmlParser:
|
||||
@staticmethod
|
||||
def parse_size(size):
|
||||
units = {"B": 1, "K": 2 ** 10, "M": 2 ** 20, "G": 2 ** 30, "T": 2 ** 40}
|
||||
size = size.upper()
|
||||
logging.debug("parsing size %s" % size)
|
||||
if not re.match(r" ", size):
|
||||
size = re.sub(r"([BKMGT])", r" \1", size)
|
||||
try:
|
||||
number, unit = [string.strip() for string in size.split()]
|
||||
except ValueError:
|
||||
number = size
|
||||
unit = "B"
|
||||
|
||||
ret = int(float(number) * units[unit])
|
||||
|
||||
return ret
|
||||
|
||||
def parse(self, install=None):
|
||||
try:
|
||||
tree = ET.parse(self.xml)
|
||||
except Exception:
|
||||
logging.error(self.xml + " is not a vaild xml file")
|
||||
raise
|
||||
|
||||
root = tree.getroot()
|
||||
self.storage = root.attrib["type"]
|
||||
install_dir = install
|
||||
parts = []
|
||||
for part in root:
|
||||
p = dict()
|
||||
if "size_in_kb" in part.attrib:
|
||||
p["part_size"] = int(part.attrib["size_in_kb"]) * 1024
|
||||
elif "size_in_b" in part.attrib:
|
||||
p["part_size"] = int(part.attrib["size_in_b"])
|
||||
else:
|
||||
p["part_size"] = sys.maxsize
|
||||
# Assign 0 means biggest number
|
||||
|
||||
if part.attrib["file"] and install_dir is not None:
|
||||
path = os.path.join(install_dir, part.attrib["file"])
|
||||
try:
|
||||
file_size = os.stat(path).st_size
|
||||
except Exception:
|
||||
file_size = 0
|
||||
if file_size > p["part_size"]:
|
||||
logging.error(
|
||||
"Image: %s(%d) is larger than partition size(%d)"
|
||||
% (part.attrib["file"], file_size, p["part_size"])
|
||||
)
|
||||
raise OverflowError
|
||||
p["file_path"] = path
|
||||
logging.debug("size of " + path + " : " + str(file_size))
|
||||
else:
|
||||
file_size = 0
|
||||
|
||||
p["file_size"] = int(file_size)
|
||||
p["file_name"] = part.attrib["file"]
|
||||
p["label"] = part.attrib["label"]
|
||||
p["mountpoint"] = (
|
||||
part.attrib["mountpoint"] if "mountpoint" in part.attrib else None
|
||||
)
|
||||
p["type"] = part.attrib["type"] if "type" in part.attrib else ""
|
||||
p["options"] = part.attrib["options"] if "options" in part.attrib else None
|
||||
|
||||
parts.append(p)
|
||||
|
||||
if self.storage == "emmc":
|
||||
self.__calEmmcOffset(parts)
|
||||
elif self.storage == "spinor":
|
||||
self.__calNorOffset(parts)
|
||||
elif self.storage == "spinand":
|
||||
self.__calNandOffset(parts)
|
||||
elif self.storage == "sd":
|
||||
self.__calNandOffset(parts)
|
||||
elif self.storage == "none":
|
||||
self.__calNandOffset(parts)
|
||||
|
||||
else:
|
||||
logging.error("Unknown storage type")
|
||||
raise ValueError(self.storage)
|
||||
for p in parts:
|
||||
self.parts[p["label"]] = p
|
||||
return parts
|
||||
|
||||
def __calEmmcOffset(self, parts):
|
||||
# EMMC will program gpt in the beggining of the emmc, start from 8192
|
||||
start = 0
|
||||
for p in parts:
|
||||
p["offset"] = start
|
||||
start += p["part_size"]
|
||||
|
||||
def __calNandOffset(self, parts):
|
||||
start = 0
|
||||
for p in parts:
|
||||
p["offset"] = start
|
||||
start += p["part_size"]
|
||||
|
||||
def __calNorOffset(self, parts):
|
||||
start = 0
|
||||
for p in parts:
|
||||
p["offset"] = start
|
||||
start += p["part_size"]
|
||||
|
||||
def getStorage(self):
|
||||
return self.storage
|
||||
|
||||
def __init__(self, xml):
|
||||
self.xml = xml
|
||||
self.storage = "emmc"
|
||||
self.parts = dict()
|
Binary file not shown.
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import argparse
|
||||
import os
|
||||
from array import array
|
||||
import binascii
|
||||
from XmlParser import XmlParser
|
||||
from tempfile import TemporaryDirectory
|
||||
import shutil
|
||||
|
||||
MAX_LOAD_SIZE = 16 * 1024 * 1024
|
||||
CHUNK_TYPE_DONT_CARE = 0
|
||||
CHUNK_TYPE_CRC_CHECK = 1
|
||||
FORMAT = "%(levelname)s: %(message)s"
|
||||
logging.basicConfig(level=logging.INFO, format=FORMAT)
|
||||
|
||||
|
||||
def parse_Args():
|
||||
parser = argparse.ArgumentParser(description="Create CVITEK device image")
|
||||
|
||||
parser.add_argument(
|
||||
"file_path",
|
||||
metavar="file_path",
|
||||
type=str,
|
||||
help="the file you want to pack with cvitek image header",
|
||||
)
|
||||
parser.add_argument(
|
||||
"output_dir",
|
||||
metavar="output_folder_path",
|
||||
type=str,
|
||||
help="the folder path to install dir inclued fip,rootfs and kernel",
|
||||
)
|
||||
parser.add_argument("xml", help="path to partition xml")
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", help="increase output verbosity", action="store_true"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if args.verbose:
|
||||
logging.debug("Enable more verbose output")
|
||||
logging.getLogger().setLevel(level=logging.DEBUG)
|
||||
|
||||
return args
|
||||
|
||||
|
||||
class ImagerBuilder(object):
|
||||
def __init__(self, storage: int, output_path):
|
||||
self.storage = storage
|
||||
self.output_path = output_path
|
||||
|
||||
def packHeader(self, part):
|
||||
"""
|
||||
Header format total 64 bytes
|
||||
4 Bytes: Magic
|
||||
4 Bytes: Version
|
||||
4 Bytes: Chunk header size
|
||||
4 Bytes: Total chunks
|
||||
4 Bytes: File size
|
||||
32 Bytes: Extra Flags
|
||||
12 Bytes: Reserved
|
||||
"""
|
||||
with open(part["file_path"], "rb") as fd:
|
||||
magic = fd.read(4)
|
||||
if magic == b"CIMG":
|
||||
logging.debug("%s has been packed, skip it!" % part["file_name"])
|
||||
return
|
||||
fd.seek(0)
|
||||
Magic = array("b", [ord(c) for c in "CIMG"])
|
||||
Version = array("I", [1])
|
||||
chunk_header_sz = 64
|
||||
Chunk_sz = array("I", [chunk_header_sz])
|
||||
chunk_counts = part["file_size"] // MAX_LOAD_SIZE
|
||||
remain = part["file_size"] - MAX_LOAD_SIZE * chunk_counts
|
||||
if (remain != 0):
|
||||
chunk_counts = chunk_counts + 1
|
||||
Totak_chunk = array("I", [chunk_counts])
|
||||
File_sz = array("I", [part["file_size"] + (chunk_counts * chunk_header_sz)])
|
||||
try:
|
||||
label = part["label"]
|
||||
except KeyError:
|
||||
label = "gpt"
|
||||
Extra_flags = array("B", [ord(c) for c in label])
|
||||
for _ in range(len(label), 32):
|
||||
Extra_flags.append(ord("\0"))
|
||||
|
||||
img = open(os.path.join(self.output_path, part["file_name"]), "wb")
|
||||
# Write Header
|
||||
for h in [Magic, Version, Chunk_sz, Totak_chunk, File_sz, Extra_flags]:
|
||||
h.tofile(img)
|
||||
img.seek(64)
|
||||
total_size = part["file_size"]
|
||||
offset = part["offset"]
|
||||
part_sz = part["part_size"]
|
||||
op_len = 0
|
||||
while total_size:
|
||||
chunk_sz = min(MAX_LOAD_SIZE, total_size)
|
||||
chunk = fd.read(chunk_sz)
|
||||
crc = binascii.crc32(chunk) & 0xFFFFFFFF
|
||||
if chunk_sz == MAX_LOAD_SIZE:
|
||||
op_len += chunk_sz
|
||||
else:
|
||||
op_len = part_sz - op_len
|
||||
chunk_header = self._getChunkHeader(chunk_sz, offset, op_len, crc)
|
||||
img.write(chunk_header)
|
||||
img.write(chunk)
|
||||
total_size -= chunk_sz
|
||||
offset += chunk_sz
|
||||
img.close()
|
||||
|
||||
def _getChunkHeader(self, size: int, offset: int, part_sz: int, crc32: int):
|
||||
"""
|
||||
Header format total 64 bytes
|
||||
4 Bytes: Chunk Type
|
||||
4 Bytes: Chunk data size
|
||||
4 Bytes: Program part offset
|
||||
4 Bytes: Program part size
|
||||
4 Bytes: Crc32 checksum
|
||||
"""
|
||||
logging.info("size:%x, offset:%x, part_sz:%x, crc:%x" % (size, offset, part_sz, crc32))
|
||||
Chunk = array(
|
||||
"I",
|
||||
[
|
||||
CHUNK_TYPE_CRC_CHECK,
|
||||
size,
|
||||
offset,
|
||||
part_sz,
|
||||
crc32,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
)
|
||||
return Chunk
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_Args()
|
||||
xmlParser = XmlParser(args.xml)
|
||||
install_dir = os.path.dirname(args.file_path)
|
||||
parts = xmlParser.parse(install_dir)
|
||||
storage = xmlParser.getStorage()
|
||||
tmp = TemporaryDirectory()
|
||||
imgBuilder = ImagerBuilder(storage, tmp.name)
|
||||
for p in parts:
|
||||
# Since xml parser will parse with abspath and the user input path can
|
||||
# be relative path, use file name to check.
|
||||
if os.path.basename(args.file_path) == p["file_name"]:
|
||||
if (
|
||||
storage != "emmc" and storage != "spinor"
|
||||
and p["file_size"] > p["part_size"] - 128 * 1024
|
||||
and p["mountpoint"]
|
||||
and p["mountpoint"] != ""
|
||||
):
|
||||
logging.error(
|
||||
"Imaege is too big, it will cause mount partition failed!!"
|
||||
)
|
||||
raise ValueError
|
||||
imgBuilder.packHeader(p)
|
||||
tmp_path = os.path.join(tmp.name, p["file_name"])
|
||||
out_path = os.path.join(args.output_dir, p["file_name"])
|
||||
logging.debug("Moving %s -> %s" % (tmp_path, out_path))
|
||||
shutil.move(tmp_path, out_path)
|
||||
logging.info("Packing %s done!" % (p["file_name"]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue