В чем разница между следующими терминами Makefile для ядра: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?


50

Просматривая файлы ядра Kernel, я нашел эти термины. Так что я хотел бы знать , в чем разница между vmlinux, vmlinuz, vmlinux.bin, zimage& bzimage?


Я думаю, что zimage - это сжатие gz, а bzimage - сжатие bz ... просто имя, afaik. Ничто из этого не значит, черт побери. но я могу ошибаться
ксенотеррацид

Ответы:


59

vmlinux

Это ядро ​​Linux в статически связанном формате исполняемого файла. Как правило, вам не нужно беспокоиться об этом файле, это всего лишь промежуточный этап процедуры загрузки.

Необработанный файл vmlinux может быть полезен для целей отладки.

vmlinux.bin

То же, что и vmlinux, но в формате загрузочного двоичного файла. Все символы и информация о перемещении отбрасываются. Сформировано из vmlinuxпути objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

Файл vmlinux обычно сжимается zlib. С 2.6.30 LZMAи bzip2также доступны. Добавив дополнительные возможности загрузки и распаковки в vmlinuz, образ можно использовать для загрузки системы с ядром vmlinux. Сжатие vmlinux может происходить с zImage или bzImage.

Функция decompress_kernel()обрабатывает распаковку vmlinuz при загрузке, сообщение указывает это:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

Это старый формат для небольших ядер (сжатый, ниже 512 КБ). При загрузке этот образ загружается с небольшим объемом памяти (первые 640 КБ ОЗУ).

bzImage ( make bzImage)

Большой zImage (это не имеет ничего общего bzip2) был создан в то время как ядро ​​росло и обрабатывает большие изображения (сжатые, более 512 КБ). Изображение загружается высоко в памяти (более 1 МБ ОЗУ). Поскольку сегодняшние ядра имеют размер более 512 КБ, это обычно предпочтительный способ.


Проверка Ubuntu 10.10 показывает:

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

Где находится эта реализация функции deppress_kernel () ?
Сен

2
Он расположен на /arch/$ARCH/boot/compressed/misc.c, смотрите здесь: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
взмах

8

Сделайте подробное построение ядра и ищите файлы

Этот подход может дать некоторое представление, никогда не устареет и поможет вам легко определить, какая часть системы сборки делает что.

Если у вас есть конфигурация сборки, которая генерирует один из файлов, выполните сборку с помощью:

make V=1 |& tee f.log

Измените комментарий к некоторому C-файлу, чтобы вызвать повторную ссылку (например, init/main.cхорошую), если вы уже создали ранее.

Теперь осмотрите f.logи найдите интересующие изображения.

Например, на v4.19 мы заключим, что:

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

Тонкие архивы упоминаются по адресу: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries/27676016#27676016 Это архивы, которые просто указывают на другие архивы / объекты, а не копируют их.

Ядро перешло от инкрементных ссылок к тонким архивам в v4.9, как описано по адресу: https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624

Полная интерпретация журнала

Когда мы начинаем читать подробные журналы сборки из резервной копии, сначала мы видим:

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

так что эти двое просто символические.

Затем мы ищем немного дальше x86/boot/bzImageи находим:

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 это исполняемый файл, поэтому мы запускаем его, смотрите сообщение справки:

Usage: build setup system zoffset.h image

и grep, чтобы найти источник:

arch/x86/boot/tools/build.c

Таким образом, этот инструмент должен генерировать arch/x86/boot/bzImageиз arch/x86/boot/vmlinux.binи других файлов TODO какой смысл buildименно?

Если мы следуем, arch/x86/boot/vmlinux.binмы видим, что это просто objcopyот arch/x86/boot/compressed/vmlinux:

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

и arch/x86/boot/compressed/vmlinuxэто просто обычный файл 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 -hlSrговорит, что piggy.oэто самый большой файл, поэтому мы ищем его, и он должен быть получен из:

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_ префикс поясняется ниже.

arch/x86/boot/compressed/piggy.S содержит:

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

см. также: https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc/36295692#36295692

arch/x86/boot/compressed/vmlinux.bin.gz происходит от:

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

который исходит из:

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

который исходит из:

LD      vmlinux

который делает:

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Огромный, но все показанные объекты являются крошечными ls -l, поэтому я исследовал и узнал о новой arфункции, о которой я не знал: тонкие архивы.

В:

AR      built-in.a

сборка делает:

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 указывает тонкий архив.

Затем мы можем видеть, что все подархивы также тонкие, например, так как я изменил init/main.c, мы имеем:

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

который в итоге приходит из файла C с помощью команды вроде:

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

Я не могу найти init/.tmp_main.oк init/main.oшагу на бревнах , который является позором ... с:

git grep '\.tmp_'

мы видим, что это, скорее всего, исходит scripts Makefile.buildи связано с тем, CONFIG_MODVERSIONSчто я включил:

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

Анализ сделан с этим конфигом, который содержит CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Просто несжатый objcopyиз vmlinux:

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

vmlinux получается в основном точно так же, как и для x86 через тонкие архивы.

arch/arm/boot/zImage

Очень похоже на X86 с молнией vmlinux, но без магического build.cшага. Сводка цепочки вызовов:

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 может загружаться с bzImage, но не с vmlinux

Это еще одно важное практическое отличие: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu



1

vmlinux :

Несжатый и не загружаемый формат файла ядра Linux, просто промежуточный шаг к созданию vmlinuz.

vmlinuz :
сжатый и загрузочный файл ядра Linux. Это на самом деле zImageили bzImageфайл.

zImage :
Для старых ядер просто подгоните640k размер оперативной памяти .

bzImage :,
Big zImageбез 640kограничения размера оперативной памяти , может гораздо больше.

Пожалуйста, обратитесь этот документ: vmlinuz Определение .


1

bzImage - цель, используемая для архитектур x86, работающих с BIOS компьютера. Напротив, zImage - это специфичная для архитектуры цель, наиболее часто используемая для встраиваемых устройств и хорошо работающая с их загрузчиками.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.