¿Cuál es la diferencia entre los siguientes términos Makefile del kernel: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?

50

Mientras navegaba por los Kernel Makefiles, encontré estos términos. Así que me gustaría saber cuál es la diferencia entre vmlinux, vmlinuz, vmlinux.bin, zimagey bzimage?

Sen
fuente
Creo que zimage es una compresión gz y bzimage es una compresión bz ... pero nombrar, afaik, nada de eso significa una maldita cosa. Pero podría estar equivocado.
xenoterracide
También se vmlinuz.efiusa en Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

59

vmlinux

Este es el kernel de Linux en un formato de archivo ejecutable enlazado estáticamente. En general, no tiene que preocuparse por este archivo, es solo un paso intermedio en el procedimiento de arranque.

El archivo vmlinux sin formato puede ser útil para fines de depuración.

vmlinux.bin

Lo mismo que vmlinux, pero en un formato de archivo binario sin formato de arranque. Todos los símbolos y la información de reubicación se descartan. Generado a partir vmlinuxde objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

El archivo vmlinux generalmente se comprime con zlib. Desde 2.6.30 LZMAy bzip2también están disponibles. Al agregar más capacidades de arranque y descompresión a vmlinuz, la imagen se puede usar para arrancar un sistema con el kernel vmlinux. La compresión de vmlinux puede ocurrir con zImage o bzImage.

La función decompress_kernel()maneja la descompresión de vmlinuz en el arranque, un mensaje indica esto:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

Este es el formato antiguo para núcleos pequeños (comprimido, por debajo de 512 KB). En el arranque, esta imagen se carga con poca memoria (los primeros 640 KB de RAM).

bzImage ( make bzImage)

La gran zImage (esto no tiene nada que ver con esto bzip2), se creó mientras el núcleo crecía y maneja imágenes más grandes (comprimidas, más de 512 KB). La imagen se carga en la memoria (por encima de 1 MB de RAM). Como los núcleos actuales superan los 512 KB, esta suele ser la forma preferida.


Una inspección en Ubuntu 10.10 muestra:

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
meneo
fuente
¿Dónde se encuentra esta implementación de la función decompress_kernel () ?
Sen
2
Se encuentra en /arch/$ARCH/boot/compressed/misc.c, ver aquí: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/…
wag
8

Realice una compilación detallada del núcleo y busque los archivos

Este enfoque puede dar una idea, nunca se desactualizará y lo ayudará a encontrar fácilmente qué parte del sistema de compilación está haciendo qué.

Una vez que tenga una configuración de compilación que genere uno de los archivos, compile con:

make V=1 |& tee f.log

Modifique un comentario en algún archivo C para forzar un reenlace (por ejemplo, init/main.ces bueno) si ya lo ha compilado anteriormente.

Ahora, inspeccione f.logy busque las imágenes de interés.

Por ejemplo, en v4.19 concluiremos 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

Los archivos delgados se mencionan en: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries/27676016#27676016 Son archivos que solo apuntan a otros archivos / objetos en lugar de copiarlos.

El núcleo se movió de la vinculación incremental a archivos delgados en v4.9 como se describe en: https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624

Interpretación completa del registro

Cuando comenzamos a leer los registros detallados de compilación desde la copia de seguridad, primero vemos:

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

entonces esos dos solo están enlazados.

Luego buscamos un poco más x86/boot/bzImagey encontramos:

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 es un ejecutable, así que lo ejecutamos, vea el mensaje de ayuda:

Usage: build setup system zoffset.h image

y grep para encontrar la fuente:

arch/x86/boot/tools/build.c

Entonces, esta herramienta debe estar generando arch/x86/boot/bzImagedesde arch/x86/boot/vmlinux.biny otros archivos TODO, ¿para qué sirve buildexactamente?

Si seguimos arch/x86/boot/vmlinux.bin, vemos que es solo objcopyde arch/x86/boot/compressed/vmlinux:

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

y arch/x86/boot/compressed/vmlinuxes solo un archivo 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 -hlSrdice que piggy.oes, con mucho, el archivo más grande, por lo que lo buscamos y debe 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_ prefijo explicado a continuación.

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

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

ver también: https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc/36295692#36295692

arch/x86/boot/compressed/vmlinux.bin.gz viene 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

que proviene de:

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

que proviene de:

LD      vmlinux

que hace:

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

vmlinuxes enorme, pero todos los objetos mostrados son pequeños de acuerdo con esto ls -l, así que investigué y aprendí sobre una nueva arcaracterística que no conocía: archivos delgados.

A:

AR      built-in.a

la construcción hace:

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 especifica el archivo delgado.

Entonces podemos ver que todos los subarchivos también son delgados, por ejemplo, desde que modifiqué init/main.c, tenemos:

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

que finalmente proviene del archivo C a través de un comando como:

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

No puedo encontrar el init/.tmp_main.oque init/main.opise los registros que es una pena ... con:

git grep '\.tmp_'

vemos que probablemente proviene scripts Makefile.buildy está vinculado a CONFIG_MODVERSIONSlo que había habilitado:

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

Análisis realizado con esta configuración que contiene CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Solo un sin comprimir objcopyde vmlinux:

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

vmlinux se obtiene básicamente de la misma manera que para x86 a través de los archivos delgados.

arch/arm/boot/zImage

Muy similar a X86 con cremallera vmlinux, pero sin build.cpaso mágico . Resumen de la cadena de llamadas:

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 puede arrancar desde bzImage pero no vmlinux

Esta es otra diferencia práctica importante: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente
1

vmlinux :

Un formato de archivo de kernel de Linux no comprimido y no arrancable, solo un paso intermedio para la producción vmlinuz.

vmlinuz :
un archivo de kernel de Linux comprimido y de arranque. En realidad es zImageo bzImagearchivo.

zImage :
para núcleos antiguos, simplemente ajuste el 640ktamaño del ram.

bzImage :
Big zImagesin 640klímite de tamaño de memoria ram, puede ser mucho más grande.

Consulte este documento: vmlinuz Definición .

Nan Xiao
fuente
1

bzImage es el objetivo utilizado para arquitecturas x86 que trabajan con BIOS de PC. Por el contrario, zImage es un objetivo específico de la arquitectura más utilizado para dispositivos integrados y funciona bien con sus cargadores de arranque.

Behnam Dezfouli
fuente