- 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
189 lines
5.7 KiB
Bash
Executable File
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"
|