Changeset 14178


Ignorieren:
Zeitstempel:
20.03.2017 07:59:56 (vor 7 Monaten)
Autor:
er13
Nachricht:

unpack-kernel script:

Datei:
1 bearbeitet

Legende:

Unverändert
Hinzugefügt
Entfernt
  • trunk/tools/unpack-kernel

    r8397 r14178  
    11#!/bin/bash 
    22 
    3 # Uncompress LZMA-packed firmware kernel. This is a functional, but 
    4 # quick & dirty version of the Perl script by Enrik Berkhan shown and explained 
    5 # at http://www.wehavemorefun.de/fritzbox/index.php/EVA. There is no CRC 
    6 # calculation for the time being and also no other kind of error checking, 
    7 # always assuming the source file is okay. The advantage of this version is 
    8 # that we do not need Perl and especially no exotic LZMA package which is 
    9 # unavailable as a Debian image, for example. The opposite is true for unlzma 
    10 # which is installed on most Linux systems in general and part of busybox-tools 
    11 # as a part of Freetz in particular. 
     3# 
     4# Uncompress LZMA-packed firmware kernel. 
     5# 
     6# Based on the format description available at http://www.wehavemorefun.de/fritzbox/LZMA-Kernel 
     7# 
    128 
    13 case $# in 
    14     2) 
    15         ;; 
    16     *) 
    17         echo "usage: $(basename "$0") <kernel_img> <uncomp_file>" >&2 
    18         echo "    kernel_img  - file starting with compressed kernel image," >&2 
    19         echo "                  e.g. kernel.image or kernel.raw" >&2 
    20         echo "    uncomp_file - uncompressed kernel output file name" >&2 
    21         echo >&2 
    22         echo "This tool also prints the kernel's load and entry addresses in a format which" >&2 
    23         echo "can be parsed and re-used as parameters for tools/lzma2eva:" >&2 
    24         echo "    load=0x94100000 entry=0x94411F50" >&2 
    25         exit 1 
    26 esac 
     9if [ $# -ne 2 ]; then 
     10    { 
     11        echo "usage: $(basename "$0") <kernel_img> <uncomp_file>" 
     12        echo "    kernel_img  - file starting with compressed kernel image," 
     13        echo "                  e.g. kernel.image or kernel.raw" 
     14        echo "    uncomp_file - uncompressed kernel output file name" 
     15        echo 
     16        echo "This tool also prints the kernel's load and entry addresses in a format which" 
     17        echo "can be parsed and re-used as parameters for tools/lzma2eva:" 
     18        echo "    load=0x94100000 entry=0x94411F50" 
     19    } >&2 
     20    exit 1 
     21fi 
     22 
     23SELF=$(readlink -f ${0}) 
     24 
     25. "$(dirname $SELF)/freetz_bin_functions" 
     26 
     27declare -x UNLZMA 
     28UNLZMA="${UNLZMA:-$(dirname $SELF)/unlzma}" 
     29[ -x "$UNLZMA" ] || { echo >&2 "ERROR: this script requires unlzma tool which is not found on your system, expected location of the tool is \"$UNLZMA\""; exit 1; } 
     30 
     31### 
     32 
     33inputFile="$1" 
     34outputFile="$2" 
     35 
     36# 
     37# $1 - magic sequence (in little-endian notation) 
     38# $2 - magic sequence name (used in error messages) 
     39# $3 - max expected number of matches (unlimited if omitted) 
     40# 
     41getDecOffsetOf1stMagicSequenceMatch() { 
     42    declare -a offsetCandidates=($(getDecOffsetsOfAllMatches "$inputFile" bin $(echo -n $1 | invertEndianness))) 
     43    if [ ${#offsetCandidates[@]} -eq 0 ]; then 
     44        echo >&2 "ERROR: ${2}${2:+ }magic sequence \"0x$1\" not found" 
     45        return 1 
     46    elif [ -n "$3" ] && [ ! ${#offsetCandidates[@]} -le "$3" ]; then 
     47        echo >&2 "ERROR: more ${2}${2:+ }magic sequence \"0x$1\" matches found (${#offsetCandidates[@]}) than expected ($3)" 
     48        return 2 
     49    fi 
     50    echo -n ${offsetCandidates[0]} 
     51} 
     52 
     53{ feed1281_Offset=$(getDecOffsetOf1stMagicSequenceMatch FEED1281 "TI-AR7 kernel" 1); } || exit 1 
     54 
     55if [ $feed1281_Offset -ne 0 ]; then 
     56    { feed9112_Offset=$(getDecOffsetOf1stMagicSequenceMatch FEED9112 "GRX5 kernel" 1); } || exit 1 
     57    if [ $feed9112_Offset -ne 0 ]; then 
     58        echo >&2 "ERROR: GRX5 kernel magic sequence \"0xFEED9112\" found at unexpected offset"; exit 1 
     59    fi 
     60fi 
     61 
     62{ lzmaRecordOffset=$(getDecOffsetOf1stMagicSequenceMatch 075A0201 "EVA-LZMA-record"); } || exit 1 
     63lzmaCompressedLenOffset=$((lzmaRecordOffset + 4)) 
     64lzmaCompressedLen=$(getLEu32AtOffset "$inputFile" $lzmaCompressedLenOffset) 
     65lzmaUncompressedLenOffset=$((lzmaRecordOffset + 8)) 
     66lzmaUncompressedLen=$(getLEu32AtOffset "$inputFile" $lzmaUncompressedLenOffset) 
     67lzmaCompressedChecksumOffset=$((lzmaRecordOffset + 12)) 
     68lzmaCompressedChecksum=$(getLEu32AtOffset "$inputFile" $lzmaCompressedChecksumOffset) 
     69lzmaStreamOffset=$((lzmaRecordOffset + 16)) 
    2770 
    2871( 
    29     # Get LZMA properties + dictionary size 
    30     dd if="$1" bs=1 count=5 skip=28 2>/dev/null 
    31     # Get uncompressed length (32-bit little-endian), pad to 64-bit 
    32     dd if="$1" bs=1 count=4 skip=20 2>/dev/null 
    33     dd if=/dev/zero bs=1 count=4 2>/dev/null 
    34     # Jump to compressed data, pipe into output stream 
    35     dd if="$1" bs=36 skip=1 2>/dev/null 
    36 ) | $(dirname "$0")/unlzma > "$2" 2>/dev/null 
     72    # LZMA properties (1 byte) + LZMA dictionary size (4 bytes) 
     73    dd if="$inputFile" bs=1 skip=$lzmaStreamOffset          count=5 2>/dev/null 
     74    # uncompressed length 
     75    dd if="$inputFile" bs=1 skip=$lzmaUncompressedLenOffset count=4 2>/dev/null 
     76    # padding 
     77    dd if=/dev/zero    bs=1                                 count=4 2>/dev/null 
     78    # compressed data 
     79    tail -c "+$((lzmaStreamOffset + 8 + 1))" "$inputFile" 2>/dev/null | head -c $lzmaCompressedLen 2>/dev/null 
     80) | "$UNLZMA" > "$2" 2>/dev/null 
    3781 
    38 [ $? -ne 0 ] && echo "$(basename "$0") ERROR: could not unpack kernel image" >&2 && exit 1 
     82[ $? -ne 0 ] && { echo >&2 "ERROR: failed to unpack kernel image"; exit 1; } 
    3983 
    40 tmp=$(dd if="$1" bs=4 count=2 skip=1 2>/dev/null | hexdump -C | head -n 1) 
    41 length=$(printf "%d" "0x${tmp:19:2}${tmp:16:2}${tmp:13:2}${tmp:10:2}") 
    42 load_addr=$(printf "0x%X" "0x${tmp:31:2}${tmp:28:2}${tmp:25:2}${tmp:22:2}") 
    43 tmp=$(dd if="$1" bs=1 count=4 skip=$((20+length)) 2>/dev/null | hexdump -C | head -n 1) 
    44 entry_addr=$(printf "0x%X" "0x${tmp:19:2}${tmp:16:2}${tmp:13:2}${tmp:10:2}") 
    45 echo "load=$load_addr entry=$entry_addr" 
     84getLoadAddr() { 
     85    local feedxxxxOfset=$1 
     86    echo -n 0x$(getHexContentAtOffset "$inputFile" $((feedxxxxOfset + 8)) 4 | invertEndianness) 
     87} 
     88 
     89getEntryAddr() { 
     90    local feedxxxxOfset=$1 
     91    local tiRecordLen=$(getLEu32AtOffset "$inputFile" $((feedxxxxOfset + 4))) 
     92    echo -n 0x$(getHexContentAtOffset "$inputFile" $((feedxxxxOfset + tiRecordLen + 20)) 4 | invertEndianness) 
     93} 
     94 
     95feed1281_LoadAddr=$(getLoadAddr $feed1281_Offset) 
     96feed1281_EntryAddr=$(getEntryAddr $feed1281_Offset) 
     97 
     98if [ -n "$feed9112_Offset" ]; then 
     99    feed9112_LoadAddr=$(getLoadAddr $feed9112_Offset) 
     100    feed9112_EntryAddr=$(getEntryAddr $feed9112_Offset) 
     101 
     102    if [ "$feed1281_LoadAddr" != "$feed9112_LoadAddr" ]; then 
     103        echo >&2 "WARNING: load addresses stored in TI-AR7 record ($feed1281_LoadAddr) and GRX5 record ($feed9112_LoadAddr) do not match" 
     104    fi 
     105 
     106    if [ "$feed1281_EntryAddr" != "$feed9112_EntryAddr" ]; then 
     107        echo >&2 "WARNING: entry addresses stored in TI-AR7 record ($feed1281_EntryAddr) and GRX5 record ($feed9112_EntryAddr) do not match" 
     108    fi 
     109fi 
     110 
     111echo "load=$feed1281_LoadAddr entry=$feed1281_EntryAddr" 
Hinweis: Hilfe zur Verwendung der Changeset-Ansicht finden Sie unter TracChangeset.