#!/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('/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"