work_script/CP02/extract_firmware.sh
Ching L 8f928a93e8 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
2026-01-04 15:08:17 +08:00

129 lines
3.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 用法: ./extract_firmware.sh <merged_bin> [output_prefix]
# 从合并的 bin 文件中提取 head file (firmware), tail file (IUM), 以及生成 metadata.json
#
# 文件布局:
# 0x04000: firmware (head file)
# 0x1dc00: IUM (tail file, 256 bytes)
# 0x1dd00: metadata (blocks: uint16, last_block_size: uint8)
INPUT="$1"
# 如果没有传 PREFIX使用原文件名去掉扩展名
if [ -n "$2" ]; then
PREFIX="$2"
else
# 获取文件名(不含路径),然后去掉扩展名
BASENAME=$(basename "$INPUT")
PREFIX="${BASENAME%.*}"
fi
if [ -z "$INPUT" ]; then
echo "用法: $0 <merged_bin> [output_prefix]"
echo "示例: $0 40_ufcs2.bin firmware"
echo " $0 40_ufcs2.bin # 使用原文件名作为前缀"
echo ""
echo "输出文件:"
echo " {prefix}.firmware - firmware 部分"
echo " {prefix}.ium - IUM 部分 (256 bytes)"
echo " {prefix}_metadata.json - 元数据"
echo ""
echo "注: 如果不指定 output_prefix将使用原文件名去掉扩展名"
exit 1
fi
if [ ! -f "$INPUT" ]; then
echo "错误: 文件不存在: $INPUT"
exit 1
fi
# 常量定义
FIRMWARE_OFFSET=$((0x4000)) # 16384
IUM_OFFSET=$((0x1dc00)) # 121856
METADATA_OFFSET=$((0x1dd00)) # 122112
IUM_SIZE=256
# 获取文件大小
if stat --version >/dev/null 2>&1; then
FILE_SIZE=$(stat -c%s "$INPUT") # Linux
else
FILE_SIZE=$(stat -f%z "$INPUT") # macOS
fi
echo "输入文件: $INPUT"
echo "文件大小: $FILE_SIZE bytes (0x$(printf '%x' $FILE_SIZE))"
echo ""
# 读取 metadata (位于 0x1dd00)
# 结构: uint16_t blocks (little-endian), uint8_t last_block_size
echo "读取 metadata (offset 0x1dd00)..."
METADATA=$(dd if="$INPUT" bs=1 skip=$METADATA_OFFSET count=3 2>/dev/null | xxd -p)
if [ ${#METADATA} -lt 6 ]; then
echo "错误: 无法读取 metadata"
exit 1
fi
# 解析 little-endian uint16 (blocks) 和 uint8 (last_block_size)
BLOCKS_LOW=$((16#${METADATA:0:2}))
BLOCKS_HIGH=$((16#${METADATA:2:2}))
BLOCKS=$(( BLOCKS_LOW + BLOCKS_HIGH * 256 ))
LAST_BLOCK_SIZE=$((16#${METADATA:4:2}))
echo " blocks: $BLOCKS (0x$(printf '%04x' $BLOCKS))"
echo " last_block_size: $LAST_BLOCK_SIZE (0x$(printf '%02x' $LAST_BLOCK_SIZE))"
# 计算 firmware 大小
FIRMWARE_SIZE=$(( BLOCKS * 256 + LAST_BLOCK_SIZE ))
echo " 计算出 firmware 大小: $FIRMWARE_SIZE bytes"
echo ""
# 提取 head file (firmware: 从 0x4000 开始)
HEAD_FILE="firmware.bin"
echo "提取 head file (firmware)..."
dd if="$INPUT" of="$HEAD_FILE" bs=1 skip=$FIRMWARE_OFFSET count=$FIRMWARE_SIZE status=none
if [ $? -eq 0 ]; then
ACTUAL_HEAD_SIZE=$(stat -f%z "$HEAD_FILE" 2>/dev/null || stat -c%s "$HEAD_FILE" 2>/dev/null)
echo " ✓ 已保存: $HEAD_FILE ($ACTUAL_HEAD_SIZE bytes)"
else
echo " ✗ 提取失败"
exit 1
fi
# 提取 tail file (IUM: 从 0x1dc00 开始, 256 bytes)
TAIL_FILE="ium.bin"
echo "提取 tail file (IUM)..."
dd if="$INPUT" of="$TAIL_FILE" bs=1 skip=$IUM_OFFSET count=$IUM_SIZE status=none
if [ $? -eq 0 ]; then
ACTUAL_TAIL_SIZE=$(stat -f%z "$TAIL_FILE" 2>/dev/null || stat -c%s "$TAIL_FILE" 2>/dev/null)
echo " ✓ 已保存: $TAIL_FILE ($ACTUAL_TAIL_SIZE bytes)"
else
echo " ✗ 提取失败"
exit 1
fi
# 生成 metadata.json
METADATA_FILE="metadata.json"
echo "生成 metadata.json..."
cat > "$METADATA_FILE" << EOF
{"blocks": "0x$(printf '%04x' $BLOCKS)", "lastBlockSize": "0x$(printf '%02x' $LAST_BLOCK_SIZE)"}
EOF
echo " ✓ 已保存: $METADATA_FILE"
echo ""
# 显示结果
echo "========================================="
echo "提取完成!"
echo ""
echo "输出文件:"
echo " Head (firmware): $HEAD_FILE ($ACTUAL_HEAD_SIZE bytes)"
echo " Tail (IUM): $TAIL_FILE ($ACTUAL_TAIL_SIZE bytes)"
echo " Metadata: $METADATA_FILE"
echo ""
echo "Metadata 内容:"
cat "$METADATA_FILE"
echo ""