Qual è la differenza tra i seguenti termini del Makefile del kernel: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?


50

Durante la navigazione tra i Makefile del kernel, ho trovato questi termini. Quindi vorrei sapere qual è la differenza tra vmlinux, vmlinuz, vmlinux.bin, zimage& bzimage?


ritengo che lo zimage sia la compressione gz e il bzimage sia la compressione bz ... non ho niente a che fare con una dannata cosa. Ma potrei sbagliarmi.
xenoterracide,

Risposte:


59

vmlinux

Questo è il kernel Linux in un formato di file eseguibile collegato staticamente. In generale, non devi preoccuparti di questo file, è solo un passaggio intermedio nella procedura di avvio.

Il file vmlinux non elaborato può essere utile per scopi di debug.

vmlinux.bin

Lo stesso di vmlinux, ma in un formato di file binario non elaborabile avviabile. Tutti i simboli e le informazioni di trasferimento vengono eliminati. Generato vmlinuxda objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

Il file vmlinux viene solitamente compresso con zlib. Dalle 2.6.30 LZMAe bzip2sono disponibili anche. Aggiungendo ulteriori funzionalità di avvio e decompressione a vmlinuz, l'immagine può essere utilizzata per avviare un sistema con il kernel vmlinux. La compressione di vmlinux può verificarsi con zImage o bzImage.

La funzione decompress_kernel()gestisce la decompressione di vmlinuz all'avvio, un messaggio indica questo:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

Questo è il vecchio formato per kernel piccoli (compressi, inferiori a 512 KB). All'avvio, questa immagine viene caricata con poca memoria (i primi 640 KB della RAM).

bzImage ( make bzImage)

Il grande zImage (questo non ha nulla a che fare con bzip2), è stato creato mentre il kernel cresceva e gestisce immagini più grandi (compresse, oltre 512 KB). L'immagine viene caricata in memoria (sopra 1 MB di RAM). Poiché i kernel di oggi superano i 512 KB, questo è di solito il modo preferito.


Un'ispezione su Ubuntu 10.10 mostra:

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

Dove si trova questa implementazione della funzione decompress_kernel () ?
Sen,

2
Si trova in /arch/$ARCH/boot/compressed/misc.c, vedi qui: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/…
wag

8

Crea un kernel dettagliato e cerca i file

Questo approccio può fornire alcune informazioni, non sarà mai obsoleto e ti aiuterà a trovare facilmente quale parte del sistema di generazione sta facendo cosa.

Una volta che hai una configurazione build che genera uno dei file, crea con:

make V=1 |& tee f.log

Modifica un commento su un file C per forzare un nuovo collegamento (ad esempio, init/main.cè buono) se hai già creato in precedenza.

Ora, ispeziona f.loge cerca le immagini di interesse.

Ad esempio, sulla v4.19 concluderemo che:

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

Gli archivi sottili sono menzionati su: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries/27676016#27676016 Sono archivi che puntano solo altri archivi / oggetti invece di copiarli.

Il kernel è passato dal collegamento incrementale agli archivi sottili in v4.9 come descritto su: https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624

Interpretazione completa del registro

Quando iniziamo a leggere i log dettagliati di build dal backup, per prima cosa vediamo:

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

quindi quei due sono semplicemente collegati simbolicamente.

Quindi cerchiamo un po 'più avanti x86/boot/bzImagee troviamo:

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 è un eseguibile, quindi lo eseguiamo, vedere il messaggio di aiuto:

Usage: build setup system zoffset.h image

e grep per trovare la fonte:

arch/x86/boot/tools/build.c

Quindi questo strumento deve generare arch/x86/boot/bzImageda arch/x86/boot/vmlinux.bine altri file TODO qual è buildesattamente il punto ?

Se seguiamo arch/x86/boot/vmlinux.binvediamo che è solo un objcopyda arch/x86/boot/compressed/vmlinux:

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

ed arch/x86/boot/compressed/vmlinuxè solo un normale file ELF:

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 -hlSrdice che piggy.oè di gran lunga il file più grande, quindi lo cerchiamo e deve provenire da:

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_ prefisso spiegato di seguito.

arch/x86/boot/compressed/piggy.S contiene:

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

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

arch/x86/boot/compressed/vmlinux.bin.gz viene da:

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

che viene da:

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

che viene da:

LD      vmlinux

che fa:

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

vmlinuxè enorme, ma tutti gli oggetti mostrati sono minuscoli in base a ls -l, quindi ho cercato e appreso una nuova arfunzionalità che non conoscevo: archivi sottili.

A:

AR      built-in.a

la build fa:

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 specifica l'archivio sottile.

Possiamo quindi vedere che anche tutti gli archivi secondari sono sottili, ad esempio, da quando ho modificato init/main.c, abbiamo:

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

che infine proviene dal file C attraverso un comando come:

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

Non riesco a trovare il init/.tmp_main.oper init/main.ocalpestare i log che è una vergogna ... con:

git grep '\.tmp_'

vediamo che probabilmente proviene scripts Makefile.builded è collegato al CONFIG_MODVERSIONSquale avevo abilitato:

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

Analisi fatta con questa configurazione che contiene CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Solo un non compresso objcopyda vmlinux:

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

vmlinux è ottenuto praticamente nello stesso modo di x86 attraverso gli archivi sottili.

arch/arm/boot/zImage

Molto simile a X86 con una cerniera vmlinux, ma nessun build.cpassaggio magico . Riepilogo della catena di chiamate:

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 può essere avviato da bzImage ma non da vmlinux

Questa è un'altra importante differenza pratica: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu



1

vmlinux :

Un formato di file del kernel Linux non compresso e non avviabile, solo un passaggio intermedio per la produzione vmlinuz.

vmlinuz :
un file del kernel Linux compresso e avviabile. In realtà è zImageo bzImagefile.

zImage :
per i vecchi kernel, basta inserire la 640kdimensione della ram.

bzImage :
Big zImage, nessun 640klimite di dimensione ariete, può molto grande.

Si prega di fare riferimento a questo documento: vmlinuz Definition .


1

bzImage è l'obiettivo utilizzato per le architetture x86 che funzionano con il BIOS del PC. Al contrario, zImage è un target specifico dell'architettura più comunemente usato per i dispositivi integrati e funziona bene con i loro bootloader.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.