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>
123 lines
3.5 KiB
Bash
Executable File
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 "" |