web-dev-qa-db-fra.com

Quelle est la différence entre les termes de fabrication du noyau suivant: vmlinux, vmlinuz, vmlinux.bin, Zimage & Bzimage?

Tout en naviguant à travers les maquillages du noyau, j'ai trouvé ces termes. Donc, j'aimerais savoir quelle est la différence entre vmlinux, vmlinuz, vmlinux.bin, zimage & bzimage?

52
Sen

vmlinux

Il s'agit du noyau Linux dans un format de fichier exécutable lié de manière statique. Généralement, vous n'avez pas à vous soucier de ce fichier, il s'agit simplement d'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

La même chose que vmlinux, mais dans un format de fichier binaire brut amorçable. Tous les symboles et les informations relocalisés sont supprimés. Généré à partir de vmlinux par objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

Le fichier vmlinux est généralement compressé avec zlib. Depuis 2.6.30 LZMA et bzip2 Sont également disponibles. En ajoutant d'autres capacité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 (comprimé, inférieur à 512 Ko). Au démarrage, cette image est chargée de la mémoire basse en mémoire (le premier 640kb de la RAM).

bzimage (make bzImage)

Le grand zage (cela n'a rien à voir avec bzip2), A été créé pendant que le noyau a grandi et gère des images plus grandes (comprimées, plus de 512 Ko). L'image est chargée haute en mémoire (au-dessus de 1 Mo de RAM). Comme les noyaux d'aujourd'hui sont debout de plus de 512 Ko, c'est généralement la voie 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 ([email protected], RO-rootFS, root_dev 0x6801, swap_dev 0x4, Normal VGA
59
wag

Faites une construction de noyau verbose et recherchez les fichiers

Cette approche peut donner une idée, ne sera jamais obsolue et vous aidera à déterminer facilement quelle partie du système de construction fait quoi.

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

make V=1 |& tee f.log

Modifier un commentaire sur certains fichiers C pour forcer un re-Link (par ex. init/main.c est un bon) si vous avez déjà construit précédemment.

Maintenant, inspectez f.log et rechercher les images d'intérêt.

Par exemple, sur le 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 à l'adresse suivante: https: //stactflow.com/questions/2157629/Quinking-Static-librarles-a-Autres-static-libres/27676016#27676016 Ils sont archives qui pointent que Autres archives/objets au lieu de les copier.

Le noyau passe de la liaison incrémentielle à des archives minces dans V4.9, comme décrit à l'adresse suivante: https: //stactflow.com/questions/29391965/Quelle-is-partiale-linking-in-gnu-linker/53959624#53959624#53959624

Interprétation du journal complet

Lorsque nous commençons à lire les journaux de construction verbose à partir de la sauvegarde, nous voyons d'abord:

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

donc, ces deux sont juste liés au symbolisme.

Ensuite, nous cherchons un peu plus loin pour x86/boot/bzImage et trouve:

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, alors nous l'exécutons, 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/bzImage de Arch/x86/boot/vmlinux.bin Et d'autres dossiers toDO quel est le point de build exactement?

Si nous suivons Arch/x86/boot/vmlinux.bin Nous voyons que c'est juste un objcopy de 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/vmlinux est juste un fichier elfe ordinaire:

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 -hlSr dit ça piggy.o est de loin le fichier le plus important, alors nous la recherchons, et cela doit venir 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: //stactoverflow.com/questions/4158900/Medding-Resources-in-executable-utilisateur-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

vmlinux est énorme, mais tous les objets montrés sont minuscules selon ls -l, alors j'ai étudié et j'ai appris sur une nouvelle caractéristique ar que je ne connaissais pas: 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 ensuite voir que toutes les sous-archives sont également minces, par exemple, depuis que j'ai modifié init/main.c, on a:

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 enfin 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 ne trouve pas le init/.tmp_main.o à init/main.o étape sur les journaux qui est une honte ... avec:

git grep '\.tmp_'

nous voyons que probablement vient de scripts Makefile.build et est lié à CONFIG_MODVERSIONS que j'avais activé:

ifndef CONFIG_MODVERSIONS
cmd_cc_o_c = $(CC) $(c_flags) -c -o [email protected] $<

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 [email protected] $(@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) [email protected];                  \
    fi;
endif

Analyse effectuée avec cette config qui contient CONFIG_KERNEL_GZIP=y.

Aarch64 Arch/arm64/boot/Image

Juste un _ non compressé objcopy de vmlinux:

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

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

Arch/arm/boot/zImage

Très similaire à x86 avec une zippée vmlinux, mais pas de magie build.c étape. Résumé de la chaîne d'appel:

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 de bzimage mais pas vmlinux

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

2
jgr

vmlinux :

Un format de fichier de noyau Linux non compressé et non amorfable, juste une étape intermédiaire pour produire vmlinuz.

vmlinuz :
[.____] un fichier de noyau Linux compressé et amorfable. C'est en fait zImage ou bzImage fichier.

Zimage :
Pour les vieux noyaux, juste en forme 640k Taille de la RAM.

bzimage :
[.____] Big zImage, non 640k Limite de taille RAM, peut beaucoup plus grande.

Veuillez vous reporter à ce document: Définition Vmlinuz .

1
Nan Xiao

Bzimage est la cible utilisée pour les architectures x86 travaillant avec le BIOS PC. En revanche, ZIMAGE est une cible spécifique à une architecture la plus couramment utilisée pour les appareils incorporés et fonctionne bien avec leurs chargeurs de démarrage.

1
Behnam Dezfouli