Was ist der Unterschied zwischen den folgenden Kernel-Makefile-Begriffen: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?

50

Beim Durchsuchen der Kernel-Makefiles habe ich diese Begriffe gefunden. So würde Ich mag wissen , was ist der Unterschied zwischen vmlinux, vmlinuz, vmlinux.bin, zimageund bzimage?

Sen
quelle
Übergröße Ich denke, Zimage ist GZ-Komprimierung und BZimage ist BZ-Komprimierung. aber ich könnte mich irren.
Xenoterracide
Es wird auch vmlinuz.efiauf Ubuntu 14.04 verwendet: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ciro Santilli新疆改造中心法轮功六四事件

Antworten:

59

vmlinux

Dies ist der Linux-Kernel in einem statisch verknüpften ausführbaren Dateiformat. Im Allgemeinen müssen Sie sich um diese Datei keine Sorgen machen, sie ist nur ein Zwischenschritt beim Startvorgang.

Die rohe vmlinux-Datei kann zu Debugging-Zwecken nützlich sein.

vmlinux.bin

Dasselbe wie vmlinux, jedoch in einem bootfähigen Raw-Binärdateiformat. Alle Symbole und Versetzungsinformationen werden verworfen. Erstellt vmlinuxvon objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

Die vmlinux-Datei wird normalerweise mit komprimiert zlib. Seit 2.6.30 LZMAund bzip2sind auch verfügbar. Durch Hinzufügen weiterer Boot- und Dekomprimierungsfunktionen zu vmlinuz kann das Image zum Booten eines Systems mit dem vmlinux-Kernel verwendet werden. Die Komprimierung von vmlinux kann mit zImage oder bzImage erfolgen.

Die Funktion decompress_kernel()übernimmt die Dekomprimierung von vmlinuz beim Booten. Eine Meldung zeigt Folgendes an:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

Dies ist das alte Format für kleine Kernel (komprimiert, unter 512 KB). Beim Booten wird dieses Image nur noch wenig Arbeitsspeicher (die ersten 640 KB des Arbeitsspeichers).

bzImage ( make bzImage)

Das große zImage (das hat nichts damit zu tun bzip2) wurde erstellt, während der Kernel wuchs und größere Bilder handhabte (komprimiert, über 512 KB). Das Bild wird hoch in den Speicher geladen (über 1 MB RAM). Da die heutigen Kernel weit über 512 KB groß sind, ist dies normalerweise der bevorzugte Weg.


Eine Überprüfung auf Ubuntu 10.10 zeigt:

ls -lh /boot/vmlinuz-$(uname -r)
-rw-r--r-- 1 root root 4.1M 2010-11-24 12:21 /boot/vmlinuz-2.6.35-23-generic

file /boot/vmlinuz-$(uname -r)
/boot/vmlinuz-2.6.35-23-generic: Linux kernel x86 boot executable bzImage, version 2.6.35-23-generic (buildd@rosea, RO-rootFS, root_dev 0x6801, swap_dev 0x4, Normal VGA
wedeln
quelle
Wo befindet sich diese Implementierung der Funktion decompress_kernel () ?
Sen
2
Es befindet sich auf /arch/$ARCH/boot/compressed/misc.c, siehe hier: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
wag
8

Erstellen Sie einen ausführlichen Kernel und suchen Sie nach den Dateien

Dieser Ansatz kann einige Einblicke geben, wird nie veraltet sein und Ihnen helfen, auf einfache Weise herauszufinden, welcher Teil des Build-Systems was tut.

Sobald Sie eine Build-Konfiguration haben, die eine der Dateien generiert, erstellen Sie mit:

make V=1 |& tee f.log

Ändern Sie einen Kommentar zu einer C-Datei, um eine Neuverknüpfung zu erzwingen (z. B. init/main.ceine gute), wenn Sie diese bereits zuvor erstellt haben.

Überprüfen Sie nun die gewünschten f.logBilder und suchen Sie sie.

In Version 4.19 werden wir beispielsweise Folgendes feststellen:

init/main.c
|
| gcc -c
|
v
init/.tmp_main.o
|
| CONFIG_MODVERSIONS stuff
|
v
init/main.o
|
| ar T (thin archive)
|
v
init/built-in.a
|
| ar T (thin archive)
|
v
built-in.a
|
| ld
|
v
vmlinux (regular ELF file)
|
| objcopy
|
v
arch/x86/boot/compressed/vmlinux.bin
|
| GZIP
|
v
arch/x86/boot/compressed/vmlinux.bin.gz
|
| .incbin
|
v
arch/x86/boot/compressed/piggy.S
|
| gcc -c
|
v
arch/x86/boot/compressed/piggy.o
|
| ld
|
v
arch/x86/boot/compressed/vmlinux (regular ELF file with gzipped code)
|
| objcopy
|
v
arch/x86/boot/vmlinux.bin
|
| arch/x86/boot/tools/build.c
|
v
arch/x86/boot/bzImage

Thin-Archive werden erwähnt unter: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries/27676016#27676016 Es handelt sich um Archive, die nur auf andere Archive / Objekte verweisen, anstatt sie zu kopieren.

Der Kernel wurde von inkrementellen Verknüpfungen zu Thin Archiven in Version 4.9 verschoben, wie unter https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624 beschrieben

Vollständige Protokollinterpretation

Wenn wir die ausführlichen Build-Protokolle von Anfang an lesen, sehen wir zuerst:

ln -fsn ../../x86/boot/bzImage ./arch/x86_64/boot/bzImage

also sind diese beiden nur miteinander verbunden.

Dann suchen wir etwas weiter x86/boot/bzImageund finden:

arch/x86/boot/tools/build \
arch/x86/boot/setup.bin \
arch/x86/boot/vmlinux.bin \
arch/x86/boot/zoffset.h \
arch/x86/boot/bzImage

arch/x86/boot/tools/build ist eine ausführbare Datei, also führen wir sie aus, siehe die Hilfemeldung:

Usage: build setup system zoffset.h image

und grep um die Quelle zu finden:

arch/x86/boot/tools/build.c

Also muss dieses Tool arch/x86/boot/bzImageaus arch/x86/boot/vmlinux.binund anderen Dateien generieren . TODO, worum geht es buildgenau?

Wenn wir folgen arch/x86/boot/vmlinux.bin, sehen wir, dass es nur ein objcopyvon ist arch/x86/boot/compressed/vmlinux:

objcopy \
-O binary \
-R .note \
-R .comment \
-S arch/x86/boot/compressed/vmlinux \
arch/x86/boot/vmlinux.bin

und arch/x86/boot/compressed/vmlinuxist nur eine reguläre ELF-Datei:

ld \
-m elf_x86_64 \
-z noreloc-overflow \
-pie \
--no-dynamic-linker \
-T arch/x86/boot/compressed/vmlinux.lds \
arch/x86/boot/compressed/head_64.o \
arch/x86/boot/compressed/misc.o \
arch/x86/boot/compressed/string.o \
arch/x86/boot/compressed/cmdline.o \
arch/x86/boot/compressed/error.o \
arch/x86/boot/compressed/piggy.o \
arch/x86/boot/compressed/cpuflags.o \
arch/x86/boot/compressed/early_serial_console.o \
arch/x86/boot/compressed/kaslr.o \
arch/x86/boot/compressed/kaslr_64.o \
arch/x86/boot/compressed/mem_encrypt.o \
arch/x86/boot/compressed/pgtable_64.o \
-o arch/x86/boot/compressed/vmlinux

ls -hlSrsagt, das piggy.oist bei weitem die größte Datei, also suchen wir danach und sie muss kommen von:

gcc \
-Wp,-MD,arch/x86/boot/compressed/.piggy.o.d \
-nostdinc \
-Ilinux/arch/x86/include \
-I./arch/x86/include/generated \
-Ilinux/include \
-I./include \
-Ilinux/arch/x86/include/uapi \
-I./arch/x86/include/generated/uapi \
-Ilinux/include/uapi \
-I./include/generated/uapi \
-include linux/include/linux/kconfig.h \
-D__KERNEL__ \
-m64 \
-O2 \
-fno-strict-aliasing \
-fPIE \
-DDISABLE_BRANCH_PROFILING \
-mcmodel=small \
-mno-mmx \
-mno-sse \
-ffreestanding \
-fno-stack-protector \
-Wno-pointer-sign \
-D__ASSEMBLY__ \
-c \
-o arch/x86/boot/compressed/.tmp_piggy.o \
arch/x86/boot/compressed/piggy.S

.tmp_ Präfix unten erklärt.

arch/x86/boot/compressed/piggy.S enthält:

.incbin "arch/x86/boot/compressed/vmlinux.bin.gz"

Siehe auch: https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc/36295692#36295692

arch/x86/boot/compressed/vmlinux.bin.gz kommt von:

cat arch/x86/boot/compressed/vmlinux.bin arch/x86/boot/compressed/vmlinux.relocs | \
gzip -n -f -9 > arch/x86/boot/compressed/vmlinux.bin.gz

was kommt von:

objcopy  -R .comment -S vmlinux arch/x86/boot/compressed/vmlinux.bin

was kommt von:

LD      vmlinux

was macht:

ld \
-m elf_x86_64 \
-z max-page-size=0x200000 \
--emit-relocs \
--build-id \
-o vmlinux \
-T ./arch/x86/kernel/vmlinux.lds \
--whole-archive \
built-in.a \
--no-whole-archive \
--start-group \
lib/lib.a \
arch/x86/lib/lib.a \
--end-group \
.tmp_kallsyms2.o

vmlinuxist riesig, aber alle gezeigten Objekte sind winzig ls -l, daher habe ich nach einer neuen arFunktion gesucht und gelernt, die ich nicht kannte: dünne Archive.

Beim:

AR      built-in.a

Der Build macht:

ar \
rcsTPD \
built-in.a \
arch/x86/kernel/head_64.o \
arch/x86/kernel/head64.o \
arch/x86/kernel/ebda.o \
arch/x86/kernel/platform-quirks.o \
init/built-in.a \
usr/built-in.a \
arch/x86/built-in.a \
kernel/built-in.a \
certs/built-in.a \
mm/built-in.a \
fs/built-in.a \
ipc/built-in.a \
security/built-in.a \
crypto/built-in.a \
block/built-in.a \
lib/built-in.a \
arch/x86/lib/built-in.a \
drivers/built-in.a \
sound/built-in.a \
firmware/built-in.a \
arch/x86/pci/built-in.a \
arch/x86/power/built-in.a \
arch/x86/video/built-in.a \
net/built-in.a \
virt/built-in.a

T Gibt das Thin-Archiv an.

Wir können dann sehen, dass alle Unterarchive auch dünn sind, z. B. init/main.chaben wir seit meiner Änderung :

ar \
rcSTPD \
init/built-in.a \
init/main.o \
init/version.o \
init/do_mounts.o \
init/do_mounts_initrd.o \
init/initramfs.o \
init/calibrate.o \
init/init_task.o

Das kommt schließlich aus der C-Datei durch einen Befehl wie:

gcc \
-Wp,-MD,init/.main.o.d \
-c \
-o \
init/.tmp_main.o \
/work/linux-kernel-module-cheat/submodules/linux/init/main.c

Ich kann das nicht finden init/.tmp_main.o, init/main.oum auf die Protokolle zu treten, was eine Schande ist ... mit:

git grep '\.tmp_'

wir sehen das kommt wahrscheinlich von scripts Makefile.buildund ist mit dem verbunden CONFIG_MODVERSIONSwas ich aktiviert hatte:

ifndef CONFIG_MODVERSIONS
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<

else
# When module versioning is enabled the following steps are executed:
# o compile a .tmp_<file>.o from <file>.c
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
#   not export symbols, we just rename .tmp_<file>.o to <file>.o and
#   are done.
# o otherwise, we calculate symbol versions using the good old
#   genksyms on the preprocessed source and postprocess them in a way
#   that they are usable as a linker script
# o generate <file>.o from .tmp_<file>.o using the linker to
#   replace the unresolved symbols __crc_exported_symbol with
#   the actual value of the checksum generated by genksyms

cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<

cmd_modversions_c =                             \
    if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then     \
        $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))  \
            > $(@D)/.tmp_$(@F:.o=.ver);                 \
                                        \
        $(LD) $(KBUILD_LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)       \
            -T $(@D)/.tmp_$(@F:.o=.ver);                \
        rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);        \
    else                                    \
        mv -f $(@D)/.tmp_$(@F) $@;                  \
    fi;
endif

Analyse mit dieser Konfiguration durchgeführt, die enthält CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Nur eine unkomprimierte objcopyvon vmlinux:

objcopy  -O binary -R .note -R .note.gnu.build-id -R .comment -S vmlinux arch/arm64/boot/Image

vmlinux wird im Grunde auf die gleiche Weise wie für x86 durch die dünnen Archive erhalten.

arch/arm/boot/zImage

Sehr ähnlich zu X86 mit einem Reißverschluss vmlinux, aber ohne Zauberschritt build.c. Zusammenfassung der Aufrufkette:

objcopy -O binary -R .comment -S  arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage

ld \
-EL \
--defsym _kernel_bss_size=469592 \
-p \
--no-undefined \
-X \
-T arch/arm/boot/compressed/vmlinux.lds \
arch/arm/boot/compressed/head.o \
arch/arm/boot/compressed/piggy.o \
arch/arm/boot/compressed/misc.o \
arch/arm/boot/compressed/decompress.o \
arch/arm/boot/compressed/string.o \
arch/arm/boot/compressed/hyp-stub.o \
arch/arm/boot/compressed/lib1funcs.o \
arch/arm/boot/compressed/ashldi3.o \
arch/arm/boot/compressed/bswapsdi2.o \
-o arch/arm/boot/compressed/vmlinux

gcc \
-c \
-o arch/arm/boot/compressed/piggy.o \
linux/arch/arm/boot/compressed/piggy.S

.incbin "arch/arm/boot/compressed/piggy_data"

cat arch/arm/boot/compressed/../Image | gzip -n -f -9 > arch/arm/boot/compressed/piggy_data

objcopy -O binary -R .comment -S  vmlinux arch/arm/boot/Image

QEMU v4.0.0 kann von bzImage aber nicht von vmlinux booten

Dies ist ein weiterer wichtiger praktischer Unterschied: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu

Ciro Santilli ist ein Schauspieler
quelle
1

vmlinux :

Ein nicht komprimiertes und nicht bootfähiges Linux-Kernel-Dateiformat, nur ein Zwischenschritt zur Produktion vmlinuz.

vmlinuz :
Eine komprimierte und bootfähige Linux- Kerneldatei . Es ist tatsächlich zImageoderbzImage Datei.

zBild :
Für alte Kernel passen Sie einfach die 640kRAM-Größe an.

bzImage :
Big zImagekeine640k RAM - Größe zu begrenzen, kann viel größer.

Bitte beziehen Sie sich auf dieses Dokument: vmlinuz Definition .

Nan Xiao
quelle
1

bzImage ist das Ziel für x86-Architekturen, die mit dem PC-BIOS arbeiten. Im Gegensatz dazu ist zImage ein architekturspezifisches Ziel, das am häufigsten für eingebettete Geräte verwendet wird und mit ihren Bootloadern gut funktioniert.

Behnam Dezfouli
quelle