work_script/CP02/merge_2323_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

189 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
# Function to show usage
show_usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -o, --output FILE Output file (default: 40w.bin)"
echo " -u, --updater FILE PA768 Updater binary file"
echo " -f, --firmware FILE 2323 firmware binary file"
echo " -i, --ium FILE 2323 IUM binary file"
echo " -h, --help Show this help message"
echo ""
echo "Example:"
echo " $0 -u PA768_Updater.bin -f 2323_firmware.bin -i 2323_ium.bin -o output.bin"
echo ""
exit 1
}
# Default values
OUTPUT_FILE="40w.bin"
PA768_FILE=""
FIRMWARE_FILE=""
IUM_FILE=""
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-o | --output)
OUTPUT_FILE="$2"
shift 2
;;
-u | --updater)
PA768_FILE="$2"
shift 2
;;
-f | --firmware)
FIRMWARE_FILE="$2"
shift 2
;;
-i | --ium)
IUM_FILE="$2"
shift 2
;;
-h | --help)
show_usage
;;
*)
echo "Unknown option: $1"
show_usage
;;
esac
done
# Configuration
MAX_LENGTH=0x1df00 # 122,624 bytes
# Convert hex to decimal for dd
MAX_LENGTH_DEC=$((MAX_LENGTH)) # 122,624 bytes
IUM_OFFSET=$((0x1dc00)) # 121,856 bytes
METADATA_OFFSET=$((0x1dd00)) # 121,088 bytes
echo "Creating merged binary file: $OUTPUT_FILE"
echo "Maximum file size: $MAX_LENGTH ($MAX_LENGTH_DEC bytes)"
echo ""
echo "Input files:"
echo " PA768 Updater: ${PA768_FILE:-"(not specified)"}"
echo " Firmware: ${FIRMWARE_FILE:-"(not specified)"}"
echo " IUM: ${IUM_FILE:-"(not specified)"}"
echo ""
# Step 1: Create initial file filled with 0xFF bytes
echo "Step 1: Creating base file filled with 0xFF..."
dd if=/dev/zero bs=1 count=$MAX_LENGTH_DEC 2>/dev/null | LC_ALL=C tr "\000" "\377" >"$OUTPUT_FILE"
if [ $? -ne 0 ]; then
echo "Error: Failed to create base file"
exit 1
fi
# Step 2: Write PA768_Updater.bin at offset 0 (entire file)
echo "Step 2: Writing PA768_Updater.bin at offset 0..."
if [ -n "$PA768_FILE" ] && [ -f "$PA768_FILE" ]; then
UPDATER_SIZE=$(stat -f%z "$PA768_FILE" 2>/dev/null || stat -c%s "$PA768_FILE" 2>/dev/null)
echo " Updater size: $UPDATER_SIZE bytes"
dd if="$PA768_FILE" of="$OUTPUT_FILE" bs=1 conv=notrunc 2>/dev/null
echo " ✓ PA768_Updater.bin written successfully"
elif [ -n "$PA768_FILE" ]; then
echo " ✗ Error: $PA768_FILE not found"
exit 1
else
echo " - PA768_Updater.bin skipped (not specified)"
fi
# Step 3: Write firmware at offset 0x4000 (16,384) - entire file
echo "Step 3: Writing firmware at offset 0x4000..."
if [ -n "$FIRMWARE_FILE" ] && [ -f "$FIRMWARE_FILE" ]; then
# Get firmware file size first
FIRMWARE_SIZE=$(stat -f%z "$FIRMWARE_FILE" 2>/dev/null || stat -c%s "$FIRMWARE_FILE" 2>/dev/null)
# Calculate blocks for 2323_firmware.bin
BLOCK_SIZE=256
FIRMWARE_BLOCKS=$((FIRMWARE_SIZE / BLOCK_SIZE))
LAST_BLOCK_SIZE=$((FIRMWARE_SIZE % BLOCK_SIZE))
echo " Firmware size: $FIRMWARE_SIZE bytes"
echo " Complete blocks: $FIRMWARE_BLOCKS"
echo " Last block size: $LAST_BLOCK_SIZE bytes"
dd if="$FIRMWARE_FILE" of="$OUTPUT_FILE" bs=1 seek=16384 conv=notrunc 2>/dev/null
echo " ✓ 2323_firmware.bin written successfully"
# Write metadata at 0x1dd00
echo "Step 3a: Writing firmware metadata at offset 0x1dd00..."
# Create metadata structure using Python for reliable binary output
python3 -c "
import struct
blocks = $FIRMWARE_BLOCKS
last_size = $LAST_BLOCK_SIZE
# struct UserFirmwareMetadata: uint16_t blocks, uint8_t last_block_size, uint8_t reserved[13]
metadata = struct.pack('<HB13x', blocks, last_size) # little-endian uint16 + uint8 + 13 zero bytes
with open('temp_metadata.bin', 'wb') as f:
f.write(metadata)
print(f' Metadata: blocks={blocks} (0x{blocks:04x}), last_block_size={last_size} (0x{last_size:02x})')
"
# Write metadata to file
dd if=temp_metadata.bin of="$OUTPUT_FILE" bs=1 seek=$METADATA_OFFSET conv=notrunc 2>/dev/null
rm temp_metadata.bin
echo " ✓ Firmware metadata written successfully"
elif [ -n "$FIRMWARE_FILE" ]; then
echo " ✗ Error: $FIRMWARE_FILE not found"
exit 1
else
echo " - Firmware skipped (not specified)"
FIRMWARE_SIZE=0
FIRMWARE_BLOCKS=0
LAST_BLOCK_SIZE=0
fi
# Step 4: Write IUM data at offset 0x1dc00 (121,856)
echo "Step 4: Writing IUM data at offset 0x1dc00..."
if [ -n "$IUM_FILE" ] && [ -f "$IUM_FILE" ]; then
IUM_SIZE=$(stat -f%z "$IUM_FILE" 2>/dev/null || stat -c%s "$IUM_FILE" 2>/dev/null)
echo " IUM size: $IUM_SIZE bytes"
dd if="$IUM_FILE" of="$OUTPUT_FILE" bs=1 count=256 seek=$IUM_OFFSET conv=notrunc 2>/dev/null
echo " ✓ 2323_ium.bin written successfully"
elif [ -n "$IUM_FILE" ]; then
echo " ✗ Error: $IUM_FILE not found"
exit 1
else
echo " - IUM data skipped (not specified)"
fi
# Verify final file size
ACTUAL_SIZE=$(stat -f%z "$OUTPUT_FILE" 2>/dev/null || stat -c%s "$OUTPUT_FILE" 2>/dev/null)
echo ""
echo "Merge completed successfully!"
echo "Output file: $OUTPUT_FILE"
echo "Expected size: $MAX_LENGTH_DEC bytes"
echo "Actual size: $ACTUAL_SIZE bytes"
if [ "$ACTUAL_SIZE" -eq "$MAX_LENGTH_DEC" ]; then
echo "✓ File size matches expected length"
else
echo "⚠ Warning: File size mismatch"
fi
# Show memory layout with firmware blocks
echo ""
echo "Memory Layout:"
if [ -n "$PA768_FILE" ]; then
echo " 0x00000 - varies: PA768_Updater.bin (entire file)"
fi
if [ -n "$FIRMWARE_FILE" ] && [ $FIRMWARE_SIZE -gt 0 ]; then
FIRMWARE_END=$((16384 + FIRMWARE_SIZE))
echo " 0x04000 - 0x$(printf '%x' $((FIRMWARE_END - 1))): 2323_firmware.bin ($FIRMWARE_SIZE bytes, $FIRMWARE_BLOCKS blocks + $LAST_BLOCK_SIZE bytes)"
echo " 0x1dd00 - 0x1dd0f: Firmware metadata (blocks=$FIRMWARE_BLOCKS, last_block_size=$LAST_BLOCK_SIZE)"
fi
if [ -n "$IUM_FILE" ]; then
echo " 0x1dc00 - 0x1dcff: 2323_ium.bin (256 bytes)"
fi
echo " Total size: $ACTUAL_SIZE bytes (0x$(printf '%x' $ACTUAL_SIZE))"
echo ""
echo "Use 'hexdump -C $OUTPUT_FILE | grep 1dd00' to verify metadata"