work_script/CP02/extract_firmware.sh
Ching L db8f25a518 feat(cp02): add firmware processing tools
- Add extract_firmware.sh for extracting firmware components from merged bins
- Add merge_2323_firmware.sh for merging PA768 updater, firmware and IUM data
- Add split_and_merge.sh for splitting firmware and creating 40W firmware
- Add comprehensive README.md with usage documentation and examples
2025-12-12 18:03:39 +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="${PREFIX}.firmware"
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="${PREFIX}.ium"
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="${PREFIX}_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 ""