work_script/CP02/extract_firmware.sh
Ching L 6ad3ab93a7 feat(cp02): add build GUI, flash guide, and comment removal tool
Add build_gui.html for visual command generation, flash_guide.md for
flashing reference, and remove_chinese_comments.py for cleaning source
files. Update extract_firmware.sh to use output directory instead of
prefix, and update README with all new tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 13:57:52 +08:00

123 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
# 用法: ./extract_firmware.sh <merged_bin> [output_dir]
# 从合并的 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"
OUTPUT_DIR="${2:-.}"
if [ -z "$INPUT" ]; then
echo "用法: $0 <merged_bin> [output_dir]"
echo "示例: $0 40_ufcs2.bin /tmp/output"
echo " $0 40_ufcs2.bin # 输出到当前目录"
echo ""
echo "输出文件:"
echo " firmware.bin - firmware 部分"
echo " ium.bin - IUM 部分 (256 bytes)"
echo " metadata.json - 元数据"
exit 1
fi
if [ ! -f "$INPUT" ]; then
echo "错误: 文件不存在: $INPUT"
exit 1
fi
# 创建输出目录(如果不存在)
mkdir -p "$OUTPUT_DIR"
# 常量定义
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="$OUTPUT_DIR/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="$OUTPUT_DIR/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="$OUTPUT_DIR/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 ""