2008年8月14日 星期四

Extract vmlinux from vmlinuz/bzImage/zImage/bootpImage

No!!! There is no way (AFAIK) to extract vmlinux from vmlinuz/bzImage/zImage/bootpImage!!!

vmlinux is an elf file of whole uncompressed kernel. We first stripped the elf header to produce the Image, a binary file, then compress it, add some decompress code to produce zImage (refer to Linux Image Generation). So we can only extract Image from vmlinuz/bzImage/zImage/bootpImage, but there is no way to obtain the original elf header, which is vmlinux.

I tried to use objcopy to add the elf header, but the result can't be used by oprofile.



I think this should also work for zImage/bootpImage, but I haven't tested yet.

http://en.wikipedia.org/wiki/Vmlinux
http://en.wikipedia.org/wiki/Vmlinux#bzImage
No specific tool exists to unpack the bzImage file, but there exists a script named extract-ikconfig, which decompresses the image and extracts build configuration directives from the image. One may modify it to get the decompressed image directly. Some distributions (e.g. Red Hat and clones) may come with a kernel-debuginfo RPM that contains the vmlinux file for the matching kernel RPM, it typically gets installed under /usr/lib/debug/lib/modules/`uname -r`/vmlinux


  1. Commnet the clean_up to prevent the temp file been removed. The echo added is for debug and information.
    extract-ikconfig
    TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1
    image="$1"
    echo ${TMPFILE}
    (............................)

    echo "ERROR: Unable to extract kernel configuration information."
    echo " This kernel image may not have the config info."

    #clean_up
    exit 1

  2. To avoid confusion, remove all /tmp/ikconfig-* first, then run extract-ikconfig in the linux source directory. The file named with ikconfig-XXXXXX in /tmp is the vmlinux extracted.
    rm /tmp/ikconfig-* -fv;
    sh scripts/extract-ikconfig /boot/vmlinuz-2.6.24-19-generic ;
    sudo cp `ls /tmp/ikconfig-*` /boot/vmlinux-2.6.24-19-generic -av;


Result:
test@test-laptop:/home/prj/linux-2.6.24-current$ rm /tmp/ikconfig-* -fv;
test@test-laptop:/home/prj/linux-2.6.24-current$ sh scripts/extract-ikconfig /boot/vmlinuz-2.6.24-19-generic ;
/tmp/ikconfig-m11819

gzip: stdin: decompression OK, trailing garbage ignored
ERROR: Unable to extract kernel configuration information.
This kernel image may not have the config info.
test@test-laptop:/home/prj/linux-2.6.24-current$ sudo cp `ls /tmp/ikconfig-*` /boot/vmlinux-2.6.24-19-generic -av;
`/tmp/ikconfig-m11819' -> `/boot/vmlinux-2.6.24-19-generic'
test@test-laptop:/home/prj/linux-2.6.24-current$






sudo objcopy -I binary -O elf32-i386 /boot/vmlinux-2.6.24-19-generic /boot/vmlinux-2.6.24-19-generic.elf

but it seems that vmlinux is not simply elf format:
root@debian:/boot# ls *-2.6.18 -al *-2.6.18.elf
-rw-r--r-- 1 root root 70682 2008-08-13 23:44 config-2.6.18
-rw------- 1 root root 2397636 2008-08-14 22:24 Image-2.6.18
-rw-r--r-- 1 root root 2398101 2008-08-14 22:34 Image-2.6.18.elf
-rw-r--r-- 1 root root 5173248 2008-08-14 19:55 initrd.img-2.6.18
-rw-r--r-- 1 root root 723178 2008-08-14 19:39 System.map-2.6.18
-rwxr-xr-x 1 root root 3401973 2008-08-14 22:19 vmlinux-2.6.18
-rw-r--r-- 1 root root 1260411 2008-08-14 19:39 vmlinuz-2.6.18


root@debian:/boot# file vmlinuz-2.6.18
vmlinuz-2.6.18: Linux kernel x86 boot executable RO-rootFS, root_dev 0x301, swap_dev 0x1, Normal VGA

root@debian:/boot# file vmlinux-2.6.18
vmlinux-2.6.18: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped

result of modified extract-ikconfig
root@debian:/boot# file Image-2.6.18
Image-2.6.18: data

result of modified extract-ikconfig and objcopy
root@debian:/boot# file Image-2.6.18.elf
Image-2.6.18.elf: ELF 32-bit LSB relocatable, no machine, version 1 (SYSV), not stripped

root@debian:/boot# readelf -h vmlinuz-2.6.18
readelf: Error: Unable to read in 0xff bytes of section headers
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

root@debian:/boot# readelf -h vmlinux-2.6.18
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x100000
Start of program headers: 52 (bytes into file)
Start of section headers: 2442068 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 37
Section header string table index: 34

root@debian:/boot# readelf -h Image-2.6.18
readelf: Error: Unable to seek to 0xc1f92900 for section headers
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

root@debian:/boot# readelf -h Image-2.6.18.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: None
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 2397724 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 5
Section header string table index: 2


root@debian:/boot# readelf -S vmlinux-2.6.18
There are 37 section headers, starting at offset 0x254354:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS c0100000 001000 181645 00 AX 0 0 4096
[ 2] __ex_table PROGBITS c0281650 182650 0009c8 00 A 0 0 8
[ 3] .rodata PROGBITS c0283000 184000 0304ce 00 A 0 0 32
[ 4] .pci_fixup PROGBITS c02b34d0 1b44d0 000528 00 A 0 0 4
[ 5] __ksymtab PROGBITS c02b39f8 1b49f8 0045f0 00 A 0 0 4
[ 6] __ksymtab_gpl PROGBITS c02b7fe8 1b8fe8 000da8 00 A 0 0 4
[ 7] __ksymtab_unused PROGBITS c02b8d90 1b9d90 000040 00 A 0 0 4
[ 8] __kcrctab PROGBITS c02b8dd0 1b9dd0 0022f8 00 A 0 0 4
[ 9] __kcrctab_gpl PROGBITS c02bb0c8 1bc0c8 0006d4 00 A 0 0 4
[10] __kcrctab_unused PROGBITS c02bb79c 1bc79c 000020 00 A 0 0 4
[11] __ksymtab_strings PROGBITS c02bb7c0 1bc7c0 00b4bf 00 A 0 0 32
[12] __param PROGBITS c02c7000 1c8000 00035c 00 A 0 0 4
[13] .data PROGBITS c02c7360 1c8360 040f84 00 WA 0 0 32
[14] .data_nosave PROGBITS c0309000 20a000 001004 00 WA 0 0 4096
[15] .data.page_aligne PROGBITS c030b000 20c000 000800 00 WA 0 0 32
[16] .data.cacheline_a PROGBITS c030b800 20c800 006680 00 WA 0 0 32
[17] .data.read_mostly PROGBITS c0311e80 212e80 000934 00 WA 0 0 32
[18] .data.init_task PROGBITS c0314000 214000 002000 00 WA 0 0 32
[19] .smp_locks PROGBITS c0316000 216000 002ff0 00 A 0 0 4
[20] .init.text PROGBITS c0319000 219000 01b4ef 00 AX 0 0 1
[21] .init.data PROGBITS c0335000 235000 00c433 00 WA 0 0 4096
[22] .init.setup PROGBITS c0341440 241440 00057c 00 WA 0 0 4
[23] .initcall.init PROGBITS c03419bc 2419bc 0002e4 00 WA 0 0 4
[24] .con_initcall.ini PROGBITS c0341ca0 241ca0 00000c 00 WA 0 0 4
[25] .security_initcal PROGBITS c0341cac 241cac 000008 00 WA 0 0 4
[26] .altinstructions PROGBITS c0341cb4 241cb4 001fdf 00 A 0 0 4
[27] .altinstr_replace PROGBITS c0343c93 243c93 0008cf 00 AX 0 0 1
[28] .exit.text PROGBITS c0344562 244562 0005a4 00 AX 0 0 1
[29] .init.ramfs PROGBITS c0345000 245000 000086 00 A 0 0 1
[30] .data.percpu PROGBITS c03450a0 2450a0 004524 00 WA 0 0 32
[31] .bss.page_aligned NOBITS c034a000 2495c4 002000 00 WA 0 0 4
[32] .bss NOBITS c034c000 2495c4 03d294 00 WA 0 0 4096
[33] .comment PROGBITS 00000000 2495c4 00abbc 00 0 0 1
[34] .shstrtab STRTAB 00000000 254180 0001d1 00 0 0 1
[35] .symtab SYMTAB 00000000 25491c 066040 10 36 17199 4
[36] .strtab STRTAB 00000000 2ba95c 083f99 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)


root@debian:/boot# readelf -S Image-2.6.18
Image-2.6.18 Image-2.6.18-6-686 Image-2.6.18-6-686.elf Image-2.6.18.elf
root@debian:/boot# readelf -S Image-2.6.18.elf
There are 5 section headers, starting at offset 0x24961c:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .data PROGBITS 00000000 000034 2495c4 00 WA 0 0 1
[ 2] .shstrtab STRTAB 00000000 2495f8 000021 00 0 0 1
[ 3] .symtab SYMTAB 00000000 2496e4 000050 10 4 2 4
[ 4] .strtab STRTAB 00000000 249734 000061 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
And Image-2.6.18.elf can't be used for oprofile (which require the vmlinux).

沒有留言: