Reputation: 531
I am working on a shell script. I have a pre-built zImage. is it possible to know the kernel version from which this zImage was created?
I have tried with the commands updated @ Getting uname information from a compressed kernel image, but both commands are failing.
$ dd if=zImage bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' zImage | \
cut -d ':' -f 1) | zcat | grep -a 'Linux version'
dd: unrecognized operand `3165585'
Try `dd --help' for more information.
gzip: stdin: unexpected end of file
$ dd if=zImage bs=1 skip=$(LC_ALL=C grep -a -b -o $'\xFD\x37\x7A\x58\x5A\x00' zImage | \
head -n 1 | cut -d ':' -f 1) | xzcat | grep -a 'Linux version'
xzcat: (stdin): File format not recognized
Can you guide me to identify the kernel version from zImage.
Upvotes: 7
Views: 20283
Reputation: 103
An addition to Sam Protsenko's answer:
Since you do not clarify the compression algorithm used in the zImage file, I recommend you to use vmlinux-to-elf. This tool can be used to convert a zImage file to ELF file, and can recognize multiple compression algorithms(not only LZMA).
In a simple usecase, first convert a zImage file to ELF file:
./vmlinux-to-elf ./zImage ./Image
file ./Image
./Image: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped
Then, find the linux version with strings
strings ./Image | grep 'Linux version'
Linux version 3.4.0-gd59db4e ([email protected]) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Mon Mar 17 15:16:36 PDT 2014
Upvotes: 1
Reputation: 14743
Most likely your zImage
was compressed using LZMA compressor. You can check it in next files:
.config
file (if you built kernel by yourself)/boot/config-`uname -r`
file (if you are using your distribution)/proc/config.gz
file (if CONFIG_IKCONFIG_PROC
is enabled)Look for CONFIG_KERNEL_*
param:
$ cat .config | grep '^CONFIG_KERNEL_[^_]\+='
If you have CONFIG_KERNEL_LZMA=y
set, it means LZMA compressor is used.
LZMA format has 5d 00 00
header signature. So one can find position of compressed Image
file in zImage
file this way:
$ grep -P -a -b -m 1 --only-matching '\x5D\x00\x00' zImage | cut -f 1 -d :
To extract compressed Image
:
$ pos=$(grep -P -a -b -m 1 --only-matching '\x5D\x00\x00' zImage | cut -f 1 -d :)
$ dd if=arch/arm/boot/zImage of=piggy.lzma bs=1 skip=$pos
Now make sure that piggy.lzma
is actually LZMA archive:
$ file piggy.lzma
piggy.lzma: LZMA compressed data, streamed
Decompress piggy.lzma
:
$ unlzma -c piggy.lzma > Image
Now that you have unpacked Image
, you can find the Linux version using strings
tool:
$ strings Image | grep 'Linux version'
which should give you something like this:
Linux version 4.4.11-188843-g94c4bf5-dirty (joe@joe-laptop) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Thu May 26 20:55:27 EEST 2016
Upvotes: 13