feat(cp02): add firmware processing and signing utilities
- Add get_last_bytes.sh to extract final 2 bytes from IUM files - Add read_bytes.sh for reading specific byte offsets from binaries - Add pack_resources.sh to package and upload CP02S resources to S3 - Add signer_new.py for firmware and bootloader signing with custom SHA1 - Update extract_firmware.sh to use fixed output filenames - Update README.md with comprehensive documentation for new tools
This commit is contained in:
parent
c86d02552f
commit
8f928a93e8
@ -28,6 +28,49 @@
|
||||
- 解析并生成 metadata.json (blocks 和 last_block_size)
|
||||
- 如未指定前缀,自动使用原文件名
|
||||
|
||||
### get_last_bytes.sh
|
||||
- **功能**: 获取 IUM 文件的最后两个字节并以十六进制格式返回
|
||||
- **用法**: `./get_last_bytes.sh [ium_file_path]`
|
||||
- **描述**:
|
||||
- 读取 IUM 文件的最后 2 个字节
|
||||
- 反转字节顺序(交换第一和第二个字节)
|
||||
- 以十六进制格式输出结果
|
||||
- 如未指定文件路径,默认使用 ium.bin
|
||||
|
||||
### read_bytes.sh
|
||||
- **功能**: 从二进制文件的特定偏移量读取 2 个字节
|
||||
- **用法**: `./read_bytes.sh <bin_file>`
|
||||
- **描述**:
|
||||
- 从偏移量 0x1dcfe 读取 2 个字节
|
||||
- 反转字节顺序(小端序转换)
|
||||
- 返回十六进制格式的结果
|
||||
- 包含文件大小和偏移量验证
|
||||
|
||||
### pack_resources.sh
|
||||
- **功能**: 打包 CP02S 资源目录中的 .bin 文件
|
||||
- **用法**: `./pack_resources.sh`(无参数)
|
||||
- **描述**:
|
||||
- 从指定目录收集所有 .bin 文件
|
||||
- 创建包含 resources/ 作为顶级目录的 tar.gz 压缩包
|
||||
- 自动上传到 S3 存储(需要配置 AWS CLI)
|
||||
- 源目录:`/Users/ching/develop/IonBridge/files/CP02S/littlefs/resources`
|
||||
|
||||
### signer_new.py
|
||||
- **功能**: 用于签名 CP02 固件和引导加载程序的 Python 工具
|
||||
- **用法**: `python3 signer_new.py --output_dir <output_directory> [options]`
|
||||
- **选项**:
|
||||
- `--firmware <path>` - 未签名的用户应用程序固件路径
|
||||
- `--bootloader <path>` - 未签名的引导加载程序路径
|
||||
- `--output_dir <path>` - 保存签名文件的目录(必需)
|
||||
- `--enable_swd` - 启用 SWD 功能
|
||||
- `--boot_directly` - 启用直接引导到用户应用程序
|
||||
- **描述**:
|
||||
- 实现自定义 SHA1 签名算法(基于逆向工程)
|
||||
- 为固件和引导加载程序生成签名的二进制文件
|
||||
- 创建包含版本号、校验和和版权信息的元数据
|
||||
- 支持多种芯片 ID 的引导加载程序变体
|
||||
- 输出签名的二进制文件和相关 JSON 元数据
|
||||
|
||||
## 使用示例
|
||||
|
||||
```bash
|
||||
@ -40,4 +83,19 @@
|
||||
# 提取固件组件
|
||||
./extract_firmware.sh 40_ufcs2.bin firmware # 指定输出前缀
|
||||
./extract_firmware.sh merged.bin # 使用原文件名作为前缀
|
||||
|
||||
# 获取 IUM 文件的最后两个字节
|
||||
./get_last_bytes.sh ium.bin # 使用默认文件
|
||||
./get_last_bytes.sh custom_ium.bin # 指定文件路径
|
||||
|
||||
# 从二进制文件读取特定偏移量的字节
|
||||
./read_bytes.sh 40_ufcs2.bin
|
||||
|
||||
# 打包资源文件
|
||||
./pack_resources.sh # 打包并上传到 S3
|
||||
|
||||
# 签名固件
|
||||
python3 signer_new.py --firmware firmware.bin --output_dir ./output
|
||||
python3 signer_new.py --bootloader bootloader.bin --output_dir ./output --enable_swd
|
||||
python3 signer_new.py --firmware firmware.bin --bootloader bootloader.bin --output_dir ./output --boot_directly
|
||||
```
|
||||
@ -79,7 +79,7 @@ echo " 计算出 firmware 大小: $FIRMWARE_SIZE bytes"
|
||||
echo ""
|
||||
|
||||
# 提取 head file (firmware: 从 0x4000 开始)
|
||||
HEAD_FILE="${PREFIX}.firmware"
|
||||
HEAD_FILE="firmware.bin"
|
||||
echo "提取 head file (firmware)..."
|
||||
dd if="$INPUT" of="$HEAD_FILE" bs=1 skip=$FIRMWARE_OFFSET count=$FIRMWARE_SIZE status=none
|
||||
|
||||
@ -92,7 +92,7 @@ else
|
||||
fi
|
||||
|
||||
# 提取 tail file (IUM: 从 0x1dc00 开始, 256 bytes)
|
||||
TAIL_FILE="${PREFIX}.ium"
|
||||
TAIL_FILE="ium.bin"
|
||||
echo "提取 tail file (IUM)..."
|
||||
dd if="$INPUT" of="$TAIL_FILE" bs=1 skip=$IUM_OFFSET count=$IUM_SIZE status=none
|
||||
|
||||
@ -105,7 +105,7 @@ else
|
||||
fi
|
||||
|
||||
# 生成 metadata.json
|
||||
METADATA_FILE="${PREFIX}_metadata.json"
|
||||
METADATA_FILE="metadata.json"
|
||||
echo "生成 metadata.json..."
|
||||
|
||||
cat > "$METADATA_FILE" << EOF
|
||||
|
||||
28
CP02/get_last_bytes.sh
Executable file
28
CP02/get_last_bytes.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to get the last two bytes of ium file
|
||||
# Returns the bytes in 0x format
|
||||
# Usage: ./get_last_bytes.sh [ium_file_path]
|
||||
|
||||
# Use provided path or default to ium.bin
|
||||
ium_file=${1:-ium.bin}
|
||||
|
||||
if [ ! -f "$ium_file" ]; then
|
||||
echo "Error: $ium_file file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get file size
|
||||
file_size=$(stat -f%z "$ium_file")
|
||||
|
||||
if [ "$file_size" -lt 2 ]; then
|
||||
echo "Error: File is too small (less than 2 bytes)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract last 2 bytes and reverse byte order
|
||||
last_bytes=$(xxd -s -2 "$ium_file" | cut -d' ' -f2 | tr -d '\n')
|
||||
# Reverse the byte order (swap first and second byte)
|
||||
byte1=${last_bytes:0:2}
|
||||
byte2=${last_bytes:2:2}
|
||||
echo "${byte2}${byte1}"
|
||||
71
CP02/pack_resources.sh
Executable file
71
CP02/pack_resources.sh
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to pack CP02S resources directory containing only .bin files
|
||||
# Creates tar.gz with resources as top-level directory
|
||||
|
||||
SOURCE_DIR="/Users/ching/develop/IonBridge/files/CP02S/littlefs/resources"
|
||||
OUTPUT_FILE="cp02s_resources.tar.gz"
|
||||
|
||||
# Check if source directory exists
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo "Error: Source directory does not exist: $SOURCE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create temporary directory structure
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
TEMP_RESOURCES="$TEMP_DIR/resources"
|
||||
|
||||
# Create resources directory in temp
|
||||
mkdir -p "$TEMP_RESOURCES"
|
||||
|
||||
# Copy only .bin files preserving directory structure
|
||||
bin_count=0
|
||||
find "$SOURCE_DIR" -name "*.bin" -type f | while read -r file; do
|
||||
# Get relative path from source directory
|
||||
relative_path="${file#$SOURCE_DIR/}"
|
||||
target_path="$TEMP_RESOURCES/$relative_path"
|
||||
|
||||
# Create target directory if needed
|
||||
mkdir -p "$(dirname "$target_path")"
|
||||
|
||||
# Copy the file
|
||||
cp "$file" "$target_path"
|
||||
((bin_count++))
|
||||
done
|
||||
|
||||
# Check if any .bin files were found
|
||||
bin_files=$(find "$TEMP_RESOURCES" -name "*.bin" 2>/dev/null | wc -l)
|
||||
if [ "$bin_files" -eq 0 ]; then
|
||||
echo "Warning: No .bin files found in $SOURCE_DIR"
|
||||
rm -rf "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save current directory before changing
|
||||
ORIGINAL_DIR="$PWD"
|
||||
|
||||
# Create tar.gz from temp directory
|
||||
cd "$TEMP_DIR"
|
||||
tar -czf "$OUTPUT_FILE" resources/
|
||||
|
||||
# Move the archive back to original directory
|
||||
mv "$OUTPUT_FILE" "$ORIGINAL_DIR/"
|
||||
|
||||
# Return to original directory
|
||||
cd "$ORIGINAL_DIR"
|
||||
|
||||
# Cleanup temp directory
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
echo "Created $OUTPUT_FILE with resources/ containing $bin_files .bin files"
|
||||
|
||||
# Upload to S3
|
||||
echo "Uploading $OUTPUT_FILE to S3..."
|
||||
if aws --endpoint=https://s3.cn-southeast-1.ifanrprod.com --profile=iot s3 cp "$OUTPUT_FILE" s3://iot-private/batch_input/; then
|
||||
echo "Successfully uploaded $OUTPUT_FILE to S3"
|
||||
else
|
||||
echo "Error: Failed to upload to S3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
32
CP02/read_bytes.sh
Executable file
32
CP02/read_bytes.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <bin_file>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BIN_FILE="$1"
|
||||
OFFSET=0x1dcfe
|
||||
|
||||
if [ ! -f "$BIN_FILE" ]; then
|
||||
echo "Error: File '$BIN_FILE' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE_SIZE=$(stat -f%z "$BIN_FILE" 2>/dev/null || stat -c%s "$BIN_FILE" 2>/dev/null)
|
||||
DECIMAL_OFFSET=$((OFFSET))
|
||||
|
||||
if [ $DECIMAL_OFFSET -ge $FILE_SIZE ]; then
|
||||
echo "Error: Offset $OFFSET ($DECIMAL_OFFSET) exceeds file size ($FILE_SIZE bytes)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $((DECIMAL_OFFSET + 2)) -gt $FILE_SIZE ]; then
|
||||
echo "Error: Cannot read 2 bytes starting from offset $OFFSET (file too small)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BYTES=$(xxd -s $DECIMAL_OFFSET -l 2 -p "$BIN_FILE")
|
||||
BYTE1=$(echo "$BYTES" | cut -c1-2)
|
||||
BYTE2=$(echo "$BYTES" | cut -c3-4)
|
||||
echo "$BYTE2$BYTE1"
|
||||
266
CP02/signer_new.py
Normal file
266
CP02/signer_new.py
Normal file
@ -0,0 +1,266 @@
|
||||
#!/usr/bin/env python3
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from absl import logging
|
||||
import json
|
||||
import shutil
|
||||
import struct
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
# Define command-line flags
|
||||
flags.DEFINE_string('signer', None, 'Path to the unsigned user application firmware.')
|
||||
flags.DEFINE_string('firmware', None, 'Path to the unsigned user application firmware.')
|
||||
flags.DEFINE_string('bootloader', None, 'Path to the unsigned bootloader.')
|
||||
flags.DEFINE_string('output_dir', None, 'Directory to save the signed files.')
|
||||
flags.DEFINE_boolean('enable_swd', False, 'Enable SWD feature')
|
||||
flags.DEFINE_boolean('boot_directly', False, 'Enable boot directly to user application')
|
||||
|
||||
# Ensure the flags are required
|
||||
flags.mark_flag_as_required('output_dir')
|
||||
|
||||
def leftrotate(x, n):
|
||||
"""Left rotate a 32-bit integer x by n bits."""
|
||||
return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFF
|
||||
|
||||
def sha1_signer_python(data):
|
||||
"""Python implementation matching sha1_signer binary exactly (based on reverse engineering)"""
|
||||
BLOCK_LEN = 64
|
||||
FIXED_SIZE = 0x1DF00 # sha1_signer processes exactly 0x1DF00 bytes
|
||||
|
||||
# Create fixed-size buffer initialized with zeros (malloc + memset in C)
|
||||
buffer = bytearray(FIXED_SIZE)
|
||||
|
||||
# Copy file data to buffer (fread in C)
|
||||
data_to_copy = min(len(data), FIXED_SIZE)
|
||||
buffer[:data_to_copy] = data[:data_to_copy]
|
||||
# Remaining bytes stay as 0
|
||||
|
||||
# Custom initial hash values (confirmed from reverse engineering)
|
||||
hash_state = [0xef343ca7, 0x5c41a2de, 0x7ce9704f, 0x62312814, 0x4de11904]
|
||||
|
||||
def sha1_compress(block, state):
|
||||
"""Compress one 64-byte block (16 rounds only, confirmed from disassembly)"""
|
||||
a, b, c, d, e = state[0], state[1], state[2], state[3], state[4]
|
||||
|
||||
# Process only 16 rounds (cmpl $0xf in disassembly)
|
||||
for i in range(16):
|
||||
# Load schedule using big-endian (confirmed from disassembly)
|
||||
schedule = (block[i * 4] << 24) | (block[i * 4 + 1] << 16) | \
|
||||
(block[i * 4 + 2] << 8) | block[i * 4 + 3]
|
||||
|
||||
# Round function with constant 0x7ebce2a7 (confirmed from disassembly)
|
||||
f = ((b & c) | (~b & d)) & 0xFFFFFFFF
|
||||
temp = (leftrotate(a, 5) + f + e + schedule + 0x7ebce2a7) & 0xFFFFFFFF
|
||||
e = d
|
||||
d = c
|
||||
c = leftrotate(b, 30)
|
||||
b = a
|
||||
a = temp
|
||||
|
||||
# Update state
|
||||
state[0] = (state[0] + a) & 0xFFFFFFFF
|
||||
state[1] = (state[1] + b) & 0xFFFFFFFF
|
||||
state[2] = (state[2] + c) & 0xFFFFFFFF
|
||||
state[3] = (state[3] + d) & 0xFFFFFFFF
|
||||
state[4] = (state[4] + e) & 0xFFFFFFFF
|
||||
|
||||
# Process complete 64-byte blocks from fixed-size buffer
|
||||
data_len = FIXED_SIZE
|
||||
offset = 0
|
||||
while data_len - offset >= BLOCK_LEN:
|
||||
sha1_compress(buffer[offset:offset + BLOCK_LEN], hash_state)
|
||||
offset += BLOCK_LEN
|
||||
|
||||
# Handle remaining bytes and padding (standard SHA1 padding)
|
||||
block = bytearray(BLOCK_LEN)
|
||||
rem = data_len - offset
|
||||
if rem > 0:
|
||||
block[0:rem] = buffer[offset:offset + rem]
|
||||
|
||||
# Add padding byte
|
||||
block[rem] = 0x80
|
||||
rem += 1
|
||||
|
||||
# If not enough room for length, process this block and start a new one
|
||||
LENGTH_SIZE = 8
|
||||
if BLOCK_LEN - rem < LENGTH_SIZE:
|
||||
sha1_compress(bytes(block), hash_state)
|
||||
block = bytearray(BLOCK_LEN)
|
||||
|
||||
# Add message length in bits (big-endian, standard SHA1 encoding)
|
||||
length_bits = data_len * 8
|
||||
for i in range(LENGTH_SIZE):
|
||||
block[BLOCK_LEN - 1 - i] = (length_bits >> (i * 8)) & 0xFF
|
||||
|
||||
# Process final block
|
||||
sha1_compress(bytes(block), hash_state)
|
||||
|
||||
return hash_state
|
||||
|
||||
def generate_metadata_python(file_path):
|
||||
"""Generate metadata using Python implementation of sha1_signer."""
|
||||
with open(file_path, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
# Use exact clone of sha1_signer binary (based on reverse engineering)
|
||||
hash_values = sha1_signer_python(data)
|
||||
|
||||
# Convert hash values to hex strings (same format as original)
|
||||
checksum = [f"{val:08x}" for val in hash_values]
|
||||
|
||||
# Generate version number using UTC date format (YYYYMMDDHH)
|
||||
utc_now = datetime.datetime.utcnow()
|
||||
version_number = int(f"{utc_now.year:04d}{utc_now.month:02d}{utc_now.day:02d}{utc_now.hour:02d}")
|
||||
|
||||
# Set copyright
|
||||
copyright_text = "Copyright (c) ifanr Inc, All Rights Reserved."
|
||||
|
||||
return {
|
||||
"version_number": version_number,
|
||||
"checksum": checksum,
|
||||
"copyright": copyright_text
|
||||
}
|
||||
|
||||
def extract_release_id(file_path):
|
||||
"""Extract the release ID from the binary."""
|
||||
with open(file_path, 'rb') as f:
|
||||
f.seek(0xA8)
|
||||
release_id = struct.unpack('<I', f.read(4))[0]
|
||||
return f"{release_id:x}"
|
||||
|
||||
def modify_firmware(firmware_bin, metadata, enable_swd = False, boot_directly = False):
|
||||
"""Modifies the firmware binary based on the metadata."""
|
||||
if not enable_swd:
|
||||
# Insert 0xb10cdeb9 at 0x1DF10 to disable SWD
|
||||
firmware_bin = (
|
||||
firmware_bin[:0x1DF10] # Everything before 0x1DF10
|
||||
+ struct.pack("<I", 0xb10cdeb9) # Insert 0xb10cdeb9 as 4-byte little-endian
|
||||
+ firmware_bin[0x1DF14:] # Everything after 0x1DF10
|
||||
)
|
||||
if boot_directly:
|
||||
# Insert 0xb007b007 at 0x1DF14 to boot directly to user application
|
||||
firmware_bin = (
|
||||
firmware_bin[:0x1DF14] # Everything before 0x1DF14
|
||||
+ struct.pack("<I", 0xb007b007) # Insert 0xb007b007 as 4-byte little-endian
|
||||
+ firmware_bin[0x1DF18:] # Everything after 0x1DF14
|
||||
)
|
||||
|
||||
version_number = metadata.get("version_number", 0)
|
||||
firmware_bin = (
|
||||
firmware_bin[:0x1DFF0]
|
||||
+ struct.pack("<I", version_number)
|
||||
+ firmware_bin[0x1DFF4:]
|
||||
)
|
||||
|
||||
checksum = metadata.get("checksum", [0] * 5)
|
||||
for i, hexstr in enumerate(checksum):
|
||||
firmware_bin = (
|
||||
firmware_bin[: 0x1DFA0 + i * 4]
|
||||
+ struct.pack("<I", int(hexstr, 16))
|
||||
+ firmware_bin[0x1DFA4 + i * 4 :]
|
||||
)
|
||||
|
||||
copyright = metadata.get("copyright", "").encode()
|
||||
copyright = copyright[:0x30]
|
||||
if len(copyright) < 0x30:
|
||||
copyright += b"\x00" * (0x30 - len(copyright))
|
||||
firmware_bin = firmware_bin[:0x1DFC0] + copyright + firmware_bin[0x1DFEF + 1 :]
|
||||
|
||||
return firmware_bin
|
||||
|
||||
def modify_bootloader(firmware_bin, metadata):
|
||||
"""Modifies the bootloader binary based on the metadata."""
|
||||
version_number = metadata.get('version_number', 0)
|
||||
firmware_bin = firmware_bin[:0x1ff4] + struct.pack('<I', version_number) + firmware_bin[0x1ff8:]
|
||||
|
||||
flash_timestamp = metadata.get('flash_timestamp', 0)
|
||||
firmware_bin = firmware_bin[:0x1ff8] + struct.pack('<I', flash_timestamp) + firmware_bin[0x1ffc:]
|
||||
|
||||
chip_id = metadata.get('chip_id', 0)
|
||||
firmware_bin = firmware_bin[:0x1ffe] + struct.pack('<B', chip_id) + firmware_bin[0x1fff:]
|
||||
|
||||
copyright = metadata.get('copyright', '').encode()
|
||||
copyright = copyright[:0x30]
|
||||
if len(copyright) < 0x30:
|
||||
copyright += b'\x00' * (0x30 - len(copyright))
|
||||
firmware_bin = firmware_bin[:0x1fc0] + copyright + firmware_bin[0x1fef + 1:]
|
||||
|
||||
return firmware_bin
|
||||
|
||||
def copy_associated_files(file_path, output_dir):
|
||||
"""Copy the input file and associated map, txt, and elf files to the output directory."""
|
||||
base_name, _ = os.path.splitext(os.path.basename(file_path))
|
||||
for ext in ['.map', '.txt', '.elf']:
|
||||
src_file = file_path.replace('.bin', ext)
|
||||
if os.path.exists(src_file):
|
||||
shutil.copy(src_file, os.path.join(output_dir, os.path.basename(src_file)))
|
||||
|
||||
shutil.copy(file_path, os.path.join(output_dir, os.path.basename(file_path)))
|
||||
|
||||
def main(argv):
|
||||
del argv # Unused.
|
||||
|
||||
if FLAGS.firmware:
|
||||
with open(FLAGS.firmware, 'rb') as f:
|
||||
firmware_bin = f.read()
|
||||
|
||||
if len(firmware_bin) >= 0x1DF00:
|
||||
raise ValueError("Firmware is too big")
|
||||
|
||||
firmware_bin += b"\xFF" * (0x1DF00 - len(firmware_bin))
|
||||
release_id = extract_release_id(FLAGS.firmware)
|
||||
unsigned_firmware_path = os.path.join(FLAGS.output_dir, f"firmware-unsigned-{release_id}.bin")
|
||||
with open(unsigned_firmware_path, 'wb') as f:
|
||||
f.write(firmware_bin)
|
||||
|
||||
# Sign the firmware using Python implementation
|
||||
metadata = generate_metadata_python(unsigned_firmware_path)
|
||||
firmware_bin += b"\xFF" * 0x100
|
||||
signed_firmware_path = os.path.join(FLAGS.output_dir, f"firmware-{release_id}.bin")
|
||||
with open(signed_firmware_path, 'wb') as f:
|
||||
modified_firmware_bin = modify_firmware(firmware_bin, metadata, FLAGS.enable_swd, FLAGS.boot_directly)
|
||||
f.write(modified_firmware_bin)
|
||||
logging.info('Firmware %s written.', signed_firmware_path)
|
||||
|
||||
# Write the metadata file
|
||||
metadata_path = os.path.join(FLAGS.output_dir, f"firmware-{release_id}.json")
|
||||
with open(metadata_path, 'w') as f:
|
||||
json.dump(metadata, f, indent=4)
|
||||
logging.info('Metadata %s written.', metadata_path)
|
||||
copy_associated_files(FLAGS.firmware, FLAGS.output_dir)
|
||||
|
||||
if FLAGS.bootloader:
|
||||
# Sign the bootloader using Python implementation
|
||||
metadata = generate_metadata_python(FLAGS.bootloader)
|
||||
release_id = extract_release_id(FLAGS.bootloader)
|
||||
|
||||
with open(FLAGS.bootloader, 'rb') as f:
|
||||
bootloader_bin = f.read()
|
||||
|
||||
if len(bootloader_bin) > 0x1f00:
|
||||
raise ValueError('Bootloader is too big')
|
||||
bootloader_bin += b'\x00' * (0x1f00- len(bootloader_bin))
|
||||
bootloader_bin += b'\xff' * 0x10
|
||||
bootloader_bin += b'\x00' * 0xf0
|
||||
|
||||
for chip_id in range(5):
|
||||
metadata['chip_id'] = chip_id
|
||||
signed_bootloader_path = os.path.join(FLAGS.output_dir, f"bootloader-chip{chip_id}-{release_id}.bin")
|
||||
with open(signed_bootloader_path, 'wb') as f:
|
||||
modified_bootloader_bin = modify_bootloader(bootloader_bin, metadata)
|
||||
f.write(modified_bootloader_bin)
|
||||
logging.info('Bootloader %s written.', signed_bootloader_path)
|
||||
|
||||
# Write the metadata file
|
||||
metadata_path = os.path.join(FLAGS.output_dir, f"bootloader-{release_id}.json")
|
||||
with open(metadata_path, 'w') as f:
|
||||
json.dump(metadata, f, indent=4)
|
||||
logging.info('Metadata %s written.', metadata_path)
|
||||
copy_associated_files(FLAGS.bootloader, FLAGS.output_dir)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(main)
|
||||
Loading…
x
Reference in New Issue
Block a user