View Single Post
Old 04-08-2012, 03:25 AM   #1
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow getkernels - "get kernel image files" script

UPDATE: 1.4 adds the 64-byte flash header length to the file length before rounding to the next 1024-byte block size. Now we need to remake affected kernel images in pastebin (such as 4.0.1).



getkernels

Use this script to make backup copies of kernel images from an mmcblk0.img backup file, or directly from the mmc device. You can flash these images with fastboot.

usage:
./getkernels mmcblk0.img : get kernels from file
./getkernels /dev/mmcblk0 : get kernels from mmc device

output:
main_kernel.img and diags_kernel.img

supported devices:
DX/DXG/K3/K4/Touch. K3 and earlier do not have diags_kernel.

You can see the iterative design process, from linux "one-liner" scripts, through the current version, by clicking the "Show" buttons and comparing the code below.

getkernels v1.4
Spoiler:
getkernels v1.4
PHP Code:
#!/bin/sh
#===================================================================================
# getkernels v1.4 - get kernel images from kindle mmc device or backup image file
# Usage:
#   getkernels /dev/mmcblk0 : get linux kernel(s) from mmc
#   getkernels mmcblk0.img : get linux kernel(s) from file
# Copyright (C) 2012 by geekmaster
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#-----------------------------------------------------------------------------------
IN="$1" # Input Name
[[ "$IN== "" ]]&& head -n6 $0|tail -n4 && exit # if no params, show usage

BS=1024 # Block Size
S1=$((0x41000/BS)) # Start 1 (main, block number)
S2=$((0xe41000/BS)) # Start 2 (diags, block number)
DN=/dev/null
MK
=main_kernel.imgDK=diags_kernel.img                        
EM
="No linux kernels found in $IN# Error Main
ED="No diags kernel found in $IN# Error Diags
echo "Searching for linux kernels in $IN ..."                        
HD="$(dd if=$IN bs=$BS skip=$S1 count=1 2>$DN|hexdump -C|grep -B2 Linux-|cut -b-60)"
[[ "$HD== "" ]]&& echo $EM && exit                                                 
set $(echo $HD); [[ $# -lt 16 ]]&& echo $EM && exit
shift 13BO=$(((64+0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=$MK bs=$BS skip=$S1 count=$BO && echo "~> $MK"
HD="$(dd if=$IN bs=$BS skip=$S2 count=1 2>$DN|hexdump -C|grep -B2 Linux-|cut -b-60)" 
[[ "$HD== "" ]]&& echo $ED && exit                                                 
set $(echo $HD); [[ $# -lt 16 ]]&& echo $ED && exit
shift 13BO=$(((64+0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=$DK bs=$BS skip=$S2 count=$BO && echo "~> $DK
This version 1.4 adds the length of the flash header (64 bytes) before rounding up to the next 1024 bytes, so that the firmware images will never be truncated.

getkernels v1.3
Spoiler:
getkernels v1.3
PHP Code:
#!/bin/sh
#===================================================================================
# getkernels v1.3 - get kernel images from kindle mmc device or backup image file
# Usage:
#   getkernels /dev/mmcblk0 : get linux kernel(s) from mmc
#   getkernels mmcblk0.img : get linux kernel(s) from file
# Copyright (C) 2012 by geekmaster
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#-----------------------------------------------------------------------------------
IN="$1"; [[ "$IN== "" ]]&& head -n6 $0|tail -n4 && exit
BS=1024BI=$((32*1024*1024/BS)); S1=$((0x41000/BS)); S2=$((0xe41000/BS)) 
DN=/dev/nullKF=_kernel.imgMK=main$KFDK=diags$KFR=1                         
EM
="No linux kernels found in $IN"ED="No diags kernel found in $IN"
echo "Searching for linux kernels in $IN ..."                        
HD="$(dd if=$IN bs=$BS skip=$S1 count=$R 2>$DN|hexdump -C|grep -B2 Linux-|cut -b-60)"
[[ "$HD== "" ]]&& echo $EM && exit                                                 
set $(echo $HD); [[ $# -lt 16 ]]&& echo $EM && exit
shift 13BO=$(((0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=$MK bs=$BS skip=$S1 count=$BO && echo "~> $MK"
HD="$(dd if=$IN bs=$BS skip=$S2 count=$R 2>$DN|hexdump -C|grep -B2 Linux-|cut -b-60)" 
[[ "$HD== "" ]]&& echo $ED && exit                                                 
set $(echo $HD); [[ $# -lt 16 ]]&& echo $ED && exit
shift 13BO=$(((0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=$DK bs=$BS skip=$S2 count=$BO && echo "~> $DK
This version 1.3 fixed a "start address" glitch that had crept into 1.2, but can sometimes return a kernel image that could be up to 64 bytes too short because the flash header length does not include the 64-byte flash header. This version contains some left-over code from version 1.2, which actually searched the entire mmc for the start of the linux kernels (in case they change in the future). Here we reverted to fixed known start addresses, to fix a bug in 1.2.

getkernels v1.1
Spoiler:
getkernels v1.1
PHP Code:
#!/bin/sh
#===================================================================================
# getkernels v1.1 - get kernel images from mmcblk0.img or /dev/mmcblk0
# Copyright (C) 2012 by geekmaster
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#-----------------------------------------------------------------------------------
[[ "$1" == "" ]]&&echo "Usage: getkernels mmbclk0.img, or getkernels /dev/mmcblk0"&&exit
IN="$1"BS=1024BLKSIN=$((32*1024*1024/BS)); DN=/dev/null
echo "Creating main_kernel.img and diags_kernel.img files..."
HD="$(dd if=$IN bs=$BS count=$BLKSIN 2>$DN|hexdump -C|grep -B2 Linux-|cut -b-60)"
set $(echo $HD); SKIP1=$((0x$1/$BS)); shift 13BLKSOUT1=$(((0x$1$2$3$4+$BS-1)/$BS))
shift 39SKIP2=$((0x$1/$BS)); shift 13BLKSOUT2=$(((0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=main_kernel.img bs=$BS skip=$SKIP1 count=$BLKSOUT1
dd 
if=$IN of=diags_kernel.img bs=$BS skip=$SKIP2 count=$BLKSOUT2 
Now that both commands are contained in a script file, they can share input data (see $HD above), saving many seconds of execution time. Also added "user-friendly" feedback message.

getkernels v1.0
Spoiler:
getkernels v1.0
PHP Code:
#!/bin/sh
#===================================================================================
# getkernels v1.0 - get kernel images from mmcblk0.img or /dev/mmcblk0
# Copyright (C) 2012 by geekmaster
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#-----------------------------------------------------------------------------------
[[ "$1" == "" ]]&&echo "Usage: getkernels mmbclk0.img, or getkernels /dev/mmcblk0"&&exit
IN=$1BS=1024BLKSIN=$((32*1024*1024/BS)); DN=/dev/null
set 
$(dd if=$IN bs=$BS count=$BLKSIN 2>$DN|hexdump -C|grep -B2 Linux-|head -n1)
SKIP=$((0x$1/$BS));shift 13;BLKSOUT=$(((0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=main_kernel.img bs=$BS skip=$SKIP count=$BLKSOUT
set 
$(dd if=$IN bs=$BS count=$BLKSIN 2>$DN|hexdump -C|grep -B2 Linux-|tail -n3|head -n1)
SKIP=$((0x$1/$BS));shift 13;BLKSOUT=$(((0x$1$2$3$4+$BS-1)/$BS))
dd if=$IN of=diags_kernel.img bs=$BS skip=$SKIP count=$BLKSOUT 
After copying my "linux one-liner" commands (see v0.1 below) into a script file, I added the "shebang" so it can be executed as a standalone command. I converted the vars to UPPERCASE so that they would stand out in my condensed code. This "first release" version contains both complete original commands with no optimization.

getkernels v0.1
Spoiler:
getmain v0.1
PHP Code:
set $(hexdump -C mmcblk0.img|grep -B2 Linux-|head -n1);bs=1024;skip=$((0x$1/$bs));shift 13;count=$(((0x$1$2$3$4+$bs-1)/$bs));echo "skip=$skip count=$count";dd if=mmcblk0.img of=kernel.img bs=$bs skip=$skip count=$count 
getdiags v0.1
PHP Code:
set $(hexdump -C mmcblk0.img|grep -B2 Linux-|tail -n3|head -n1);bs=1024;skip=$((0x$1/$bs));shift 13;count=$(((0x$1$2$3$4+$bs-1)/$bs));echo "skip=$skip count=$count";dd if=mmcblk0.img of=diags_kernel.img bs=$bs skip=$skip count=$count 
These "linux one-liners" show how I usually create and use my scripts the first time. I reuse them from the shell command history with the up-arrow key, and use the back-arrow key to edit them. Later after tested and working, I "copy/paste" them to a file with "cat >> file.sh", then split the lines to fit the window.

Linux one-liners such as these are "fair use" ("few paragraphs" clause), and "don't need no stinkin' license". And just how would you squeeze a license into one line of code anyway?



Enjoy and learn!

(Only tested on Linux host PC, K3, K4 and Touch at this time, but should work on all of the eink kindles.)
Attached Files
File Type: gz getkernels-1.0.tar.gz (517 Bytes, 516 views)
File Type: gz getkernels-1.1.tar.gz (570 Bytes, 492 views)
File Type: gz getkernels-1.3.tar.gz (662 Bytes, 556 views)
File Type: gz getkernels-1.4.tar.gz (754 Bytes, 871 views)

Last edited by geekmaster; 08-20-2012 at 11:45 PM. Reason: add new and old versions
geekmaster is offline   Reply With Quote