- 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
129 lines
3.8 KiB
Bash
Executable File
129 lines
3.8 KiB
Bash
Executable File
#!/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 "" |