Quelle est la différence entre les termes Makefile du noyau suivants: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?

50

En parcourant les Makefiles du noyau, j'ai trouvé ces termes. Je voudrais donc savoir quelle est la différence entre vmlinux, vmlinuz, vmlinux.bin, zimage& bzimage?

Sen
la source
Je pense que zimage est une compression gz et bzimage est une compression bz ... nommer jut, autant que je sache, ça ne veut rien dire. mais je peux me tromper.
Xenoterracide
Il est également vmlinuz.efiutilisé sur Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ciro Santilli a publié

Réponses:

59

vmlinux

Il s’agit du noyau Linux dans un format de fichier exécutable lié statiquement. Généralement, vous n'avez pas à vous soucier de ce fichier, ce n'est qu'une étape intermédiaire dans la procédure de démarrage.

Le fichier vmlinux brut peut être utile à des fins de débogage.

vmlinux.bin

Identique à vmlinux, mais dans un format de fichier binaire brut amorçable. Tous les symboles et toutes les informations de déplacement sont supprimés. Généré vmlinuxpar objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

Le fichier vmlinux est généralement compressé avec zlib. Depuis 2.6.30 LZMAet bzip2sont également disponibles. En ajoutant d'autres fonctionnalités de démarrage et de décompression à vmlinuz, l'image peut être utilisée pour démarrer un système avec le noyau vmlinux. La compression de vmlinux peut se produire avec zImage ou bzImage.

La fonction decompress_kernel()gère la décompression de vmlinuz au démarrage, un message indique ceci:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

C'est l'ancien format pour les petits noyaux (compressé, inférieur à 512 Ko). Au démarrage, cette image est chargée en mémoire (les 640 premiers Ko de la RAM).

bzImage ( make bzImage)

La grande zImage (cela n'a rien à voir avec bzip2), a été créée alors que le noyau grandissait et gérait des images plus grandes (compressées, supérieures à 512 Ko). L'image est chargée en mémoire (supérieure à 1 Mo de RAM). Les noyaux actuels dépassant largement les 512 Ko, c'est généralement la méthode préférée.


Une inspection sur Ubuntu 10.10 montre:

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
remuer
la source
Où se trouve cette implémentation de la fonction decompress_kernel () ?
Sen
2
Il est situé à /arch/$ARCH/boot/compressed/misc.c, voir ici: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/…
wag le
8

Faire une compilation verbeuse du noyau et rechercher les fichiers

Cette approche peut donner un aperçu, ne sera jamais démodée et vous aidera à trouver facilement quelle partie du système de compilation fait quoi.

Une fois que vous avez une configuration de construction qui génère l’un des fichiers, construisez-la avec:

make V=1 |& tee f.log

Modifiez un commentaire sur un fichier C pour forcer une nouvelle liaison (par exemple, init/main.cun bon) si vous avez déjà construit précédemment.

Maintenant, inspectez f.loget recherchez les images qui vous intéressent.

Par exemple, sur la v4.19, nous conclurons que:

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

Les archives minces sont mentionnées sur: https://stackoverflow.com/questions/2157629/linking-static-libraries- to -other - static - libraries / 27676016#27676016. Ce sont des archives qui pointent simplement sur d'autres archives / objets au lieu de les copier.

Le noyau est passé de la liaison incrémentielle aux archives minces dans la v4.9, comme décrit à l' adresse : https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624

Interprétation complète du journal

Lorsque nous commençons à lire les journaux de construction détaillés à partir de la sauvegarde, nous voyons d’abord:

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

donc ces deux sont juste symlinked.

Ensuite, nous cherchons un peu plus loin x86/boot/bzImageet trouvons:

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 est un exécutable, nous le lançons donc, voir le message d'aide:

Usage: build setup system zoffset.h image

et grep pour trouver la source:

arch/x86/boot/tools/build.c

Donc, cet outil doit générer à arch/x86/boot/bzImagepartir d' arch/x86/boot/vmlinux.binautres fichiers TODO et à quoi sert buildexactement?

Si nous suivons, arch/x86/boot/vmlinux.binnous voyons qu'il ne s'agit que objcopyde arch/x86/boot/compressed/vmlinux:

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

et arch/x86/boot/compressed/vmlinuxest juste un fichier ELF normal:

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 -hlSrdit que piggy.oc'est de loin le fichier le plus volumineux, alors nous le recherchons, et il doit provenir de:

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éfixe expliqué ci-dessous.

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

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

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

arch/x86/boot/compressed/vmlinux.bin.gz vient de:

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

qui vient de:

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

qui vient de:

LD      vmlinux

qui fait:

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

vmlinuxest énorme, mais tous les objets montrés sont minuscules ls -l, j’ai donc cherché et découvert une nouvelle arfonctionnalité que je ne connaissais pas: les archives minces.

À:

AR      built-in.a

la construction fait:

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 spécifie l'archive mince.

Nous pouvons alors voir que toutes les sous-archives sont également minces, par exemple, depuis que j'ai modifié init/main.c, nous avons:

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

qui vient finalement du fichier C via une commande comme:

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

Je n'arrive pas à trouver le moyen init/.tmp_main.ode init/main.omarcher sur les bûches, ce qui est dommage ... avec:

git grep '\.tmp_'

nous voyons que cela vient probablement de scripts Makefile.buildet est lié à CONFIG_MODVERSIONSce que j’avais activé:

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 faite avec cette config qui contient CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Juste un non compressé objcopyde vmlinux:

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

vmlinux est obtenu de la même manière que pour les archives minces.

arch/arm/boot/zImage

Très semblable au X86 avec un zip vmlinux, mais pas d' build.cétape magique . Résumé de la chaîne d'appels:

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 peut démarrer à partir de bzImage mais pas de vmlinux

Il existe une autre différence pratique importante: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu

Ciro Santilli 改造 中心 六四 事件
la source
1

vmlinux :

Un format de fichier du noyau Linux non compressé et non amorçable, une étape intermédiaire dans la production vmlinuz.

vmlinuz :
fichier de noyau Linux compressé et amorçable. C'est réellement zImageou bzImagefichier.

zImage :
Pour les anciens noyaux, ajustez simplement la 640ktaille du bélier.

bzImage :
Big zImage, aucune 640klimite de taille de la RAM, peut beaucoup plus grande.

Veuillez vous référer à ce document: Définition de vmlinuz .

Nan Xiao
la source
1

bzImage est la cible utilisée pour les architectures x86 fonctionnant avec le BIOS du PC. En revanche, zImage est une cible spécifique à l’architecture la plus couramment utilisée pour les périphériques intégrés et fonctionne bien avec leurs chargeurs de démarrage.

Behnam Dezfouli
la source