Qual é a diferença entre os seguintes termos do Makefile do kernel: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?

43

Enquanto navegava pelos Makefiles do Kernel, encontrei estes termos. Então, eu gostaria de saber qual é a diferença entre vmlinux , vmlinuz , vmlinux.bin , zimage & bzimage ?

    
por Sen 07.01.2011 / 15:14

5 respostas

54

vmlinux

Este é o kernel do Linux em um formato de arquivo executável vinculado estaticamente. Geralmente, você não precisa se preocupar com esse arquivo, é apenas uma etapa intermediária no procedimento de inicialização.

O arquivo raw vmlinux pode ser útil para fins de depuração.

vmlinux.bin

O mesmo que vmlinux, mas em um formato de arquivo binário bruto inicializável. Todos os símbolos e informações de relocação são descartados. Gerado a partir de vmlinux por objcopy -O binary vmlinux vmlinux.bin .

vmlinuz

O arquivo vmlinux geralmente é compactado com zlib . Desde 2.6.30 LZMA e bzip2 também estão disponíveis. Adicionando mais recursos de boot e descompressão ao vmlinuz, a imagem pode ser usada para inicializar um sistema com o kernel vmlinux. A compactação do vmlinux pode ocorrer com zImage ou bzImage.

A função decompress_kernel() manipula a descompactação de vmlinuz na inicialização, uma mensagem indica isso:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage )

Este é o formato antigo para kernels pequenos (compactados, abaixo de 512KB). Na inicialização, essa imagem é carregada com pouca memória (os primeiros 640 KB da RAM).

bzImage ( make bzImage )

O grande zImage (isso não tem nada a ver com bzip2 ), foi criado enquanto o kernel cresceu e manipula imagens maiores (compactadas, acima de 512KB). A imagem é carregada em memória alta (acima de 1MB de RAM). Como os kernels de hoje estão bem acima dos 512KB, esse é normalmente o modo preferido.

Uma inspeção no 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
    
por 09.01.2011 / 18:36
6

Faça uma construção detalhada do kernel e procure pelos arquivos

Essa abordagem pode fornecer algumas dicas, nunca ficará desatualizada e ajudará você a descobrir com facilidade qual parte do sistema de criação está fazendo o quê.

Quando você tiver uma configuração de compilação que gera um dos arquivos, crie com:

make V=1 |& tee f.log

Modifique um comentário em algum arquivo C para forçar um novo link (por exemplo, init/main.c é bom) se você já tiver criado previamente.

Agora, inspecione f.log e pesquise as imagens de interesse.

Por exemplo, na 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

Arquivos finos são mencionados em: link Eles são arquivos que apenas apontam outros arquivos / objetos em vez de copiá-los.

O kernel foi movido da vinculação incremental para arquivos thin na v4.9, conforme descrito em: link

Interpretação completa do registro

Quando começamos a ler os logs de compilação detalhados do backup, primeiro vemos:

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

para que esses dois sejam apenas links simbólicos.

Em seguida, procuramos um pouco mais por x86/boot/bzImage e 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 é um executável, então nós o executamos, veja a mensagem de ajuda:

Usage: build setup system zoffset.h image

e grep para encontrar a fonte:

arch/x86/boot/tools/build.c

Então esta ferramenta deve estar gerando arch/x86/boot/bzImage de arch/x86/boot/vmlinux.bin e outros arquivos TODO qual é o ponto de build exatamente?

Se seguirmos arch/x86/boot/vmlinux.bin , veremos que é apenas um 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

e arch/x86/boot/compressed/vmlinux são apenas um arquivo 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 -hlSr diz que piggy.o é de longe o maior arquivo, então procuramos por ele e ele deve vir 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_ prefix explicado abaixo.

arch/x86/boot/compressed/piggy.S contém:

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

veja também: link

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

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

que vem de:

LD      vmlinux

qual faz:

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, mas todos os objetos mostrados são minúsculos de acordo com ls -l , então pesquisei e aprendi sobre um novo recurso ar que eu não conhecia: arquivos thin.

Em:

AR      built-in.a

o build faz:

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 o arquivo thin.

Podemos ver que todos os sub-repositórios também são pequenos, por exemplo, como eu modifiquei init/main.c , temos:

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 vem do arquivo C através de um 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

Não consigo encontrar a etapa init/.tmp_main.o to init/main.o nos registros, o que é uma pena ... com:

git grep '\.tmp_'

vemos que provavelmente vem de scripts Makefile.build e está vinculado a CONFIG_MODVERSIONS que eu tinha ativado:

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álise feita com esta configuração que contém CONFIG_KERNEL_GZIP=y .

aarch64 arch/arm64/boot/Image

Apenas um objcopy não compactado de vmlinux :

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

vmlinux é obtido basicamente da mesma maneira que para x86 por meio dos arquivos thin.

arch/arm/boot/zImage

Muito parecido com o X86 com um zip vmlinux , mas nenhuma mágica build.c step. Resumo da cadeia de chamadas:

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
    
por 20.11.2018 / 14:43
2

Está tudo aqui: link

    
por 07.01.2011 / 16:11
1

vmlinux :

Um formato de arquivo de kernel Linux não-compactado e não-inicializável, apenas uma etapa intermediária para produzir vmlinuz .

vmlinuz :
Um arquivo de kernel do Linux compactado e inicializável. Na verdade, é zImage ou bzImage file.

zImage :
Para kernels antigos, ajuste apenas o tamanho de 640k ram.

bzImage :% Big zImage , sem 640k de limite de tamanho de ram, pode ser muito maior.

Por favor, consulte este documento: Definição de vmlinuz .

    
por 28.07.2015 / 05:49
1

bzImage é o alvo usado para arquiteturas x86 que trabalham com o BIOS do PC. Em contraste, zImage é um destino específico da arquitetura mais comumente usado para dispositivos incorporados e funciona bem com seus carregadores de inicialização.

    
por 31.08.2015 / 04:32