开发者

How can I determine the build/version of Linux kernel 'uImage'?

I'm t开发者_如何学Gorying to track down a kernel binary; is there a way to determine the version (build string) of a Linux 'uImage' binary?

Running

strings uImage

piped into various trailing grep statements leads me to think I'm dealing with a compressed image...


According to kernel's format specification, here's C code:

kver.c

#include <stdio.h>

int main(int argc, char** argv){
    if (argc > 1){
        FILE* f = fopen(argv[1], "r");
        short offset = 0;
        char str[128];
        if(f){
            fseek(f, 0x20E, SEEK_SET);
            fread(&offset, 2, 1, f);
            fseek(f, offset + 0x200, SEEK_SET);
            fread(str, 128, 1, f);
            str[127] = '\0';
            printf("%s\n", str);
            fclose(f);
            return 0;
        }else {
            return 2;
        }
    } else {
        printf("use: kver [kernel image file]\n");
        return 1;
    }
}

compile and run:

gcc -o kver kver.c
./kver /boot/vmlinux-something


To find out what version of Linux is compiled, use the strings utility on the uncompressed vmlinux image.

For example:

strings linux-src/build/build-generic/vmlinux|grep "Linux version"

Sample output:

Linux version 3.2.0-56-generic (root@puerto-cayo) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #86 SMP Fri Nov 1 10:24:18 EDT 2013 (Ubuntu 3.2.0-56.86-generic 3.2.51)


I just realized, the kernels I have immediate access to do have the version string stored uncompressed amongst the headers. strings uImage | grep 2.6 ought to be good enough for any 2.6 kernel which covers pretty much everything in the last 5+ years).

(original answer follows)


It's theoretically possible, but not entirely trivial.

Modern Linux kernel versions use a format called bzImage (for x86/x86_64, YMMV on other platforms). It actually consists of an ELF header and some other minutia (like a bit of decompression code) followed by, yes, a compressed image of the actual kernel.

Traditionally, the compression algorithm was zlib (contrary to popular misconception, 'bzImage' did not stand for "bzipped image", but for "big zImage" -- the original zImage format not being able to handle large kernels), though versions after 2.6.30 also support bzip2 and LZMA.

What you'll probably have to do is determine exactly where the compressed data starts (sorry, can't help you there, but trial and error might work), and write a bit of code to run it through the library for whichever compression algorithm is in use.


Try file uImage. It might identify the file format if it is a commonly known compression format. Other than that, the strings utility is probably the best one for this task.


This will output the kernel version and the localversion string (if any was set at build time) on a bzimage:

 strings bzimage |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1

I've tested it on kernel versions 3 and 4 ... but it should also work on previous versions too.

strings vmlinuz |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1
4.4.5
strings vmlinux |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1
3.2.45-smp

If you have uImage you will haveto remove the "^" or it will not match anything

strings uImage |grep -E "[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |head -1
Linux-3.0.76


I am not sure however you might try uname -a may be this is what you want.


If it is a kernel for x86, it has the version in the header. See Documentation/x86/boot.txt (look at the kernel_version field).

I do not know if the same is true for other architectures (that header is x86-specific).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜