#! /bin/sh # # copyright - PKG.fr - 2008 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA echo echo "kernel extract v0.1" echo if [ ! -s "$1" ]; then echo "You must provide the extracted MTD file as first argument" exit 1 fi MTD="$1" BIN="$2" # Update BIN to default if not set : ${BIN:=uImage.bin} function get_int () { Hex="0x" let i=0 offset=$1 while (( i < 4 )) do Chr=$( dd if="$MTD" bs=1 count=1 skip=$((offset+i)) 2>/dev/null ) Chr=$( printf '%d' "'$Chr" ) #echo $Chr 1>&2 (( Chr < 0 )) && let Chr+=256 Hex="$Hex$( printf '%02lX' $Chr )" #echo $Hex 1>&2 let i++ done echo "$Hex" } function get_str () { Str="" let Ascii=1 offset=$1 while (( Ascii > 0 )) do Chr=$( dd if="$MTD" bs=1 count=1 skip=$((offset)) 2>/dev/null ) Ascii=$( printf '%d' "'$Chr" ) (( Ascii > 31 && Ascii < 127 )) && Str="$Str$Chr" (( ++offset >= 0x40 )) && break done echo "$Str" } # uImage.bin header used by u-boot MAGIC=$(get_int 0) HCRC=$(get_int 4) TIME=$(get_int 8) SIZE=$(get_int 12) ADDR=$(get_int 16) ADDS=$(get_int 20) DCRC=$(get_int 24) ARCH=$(get_int 28) VERS=$(get_str 32) printf "Magic=%s HCRC=%d Timestamp=%d DCRC=%d Arch=%s\n\n" $MAGIC $HCRC $TIME $DCRC $ARCH printf "Kernel size = %d\nKernel should be loaded at %s address, entry point is %s\n" $SIZE $ADDR $ADDS echo "Linux version: $VERS" echo if [ "$MAGIC" != "0x27051956" ]; then echo "Error: Found wrong magic value at offset 0" 1>&2 exit 4 fi TEST=$(get_int $(($INT1+0x40)) ) (( TEST )) && echo "Warning: bytes after the kernel are not null" if (( SIZE > 4096000 )); then echo "The kernel size seems too high, can't process" exit 2 fi # Keeping header to get uImage.bin let SIZE+=64 # Copy kernel with dd using 4 bytes block size to have minimum performance dd if=$MTD of=$BIN bs=4 count=$((SIZE/4)) echo CTRL=$( wc -c "$BIN" | cut -d ' ' -f 1 ) if [ "$CTRL" -eq "$((SIZE+64))" ]; then echo "Kernel extracted to '$BIN'" echo else echo "Kernel extraction failed ($CTRL!=$((SIZE)))" echo exit 3 fi