Просматривая файлы ядра Kernel, я нашел эти термины. Так что я хотел бы знать , в чем разница между vmlinux
, vmlinuz
, vmlinux.bin
, zimage
& bzimage
?
vmlinuz.efi
используется в Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Просматривая файлы ядра Kernel, я нашел эти термины. Так что я хотел бы знать , в чем разница между vmlinux
, vmlinuz
, vmlinux.bin
, zimage
& bzimage
?
vmlinuz.efi
используется в Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ответы:
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
/arch/$ARCH/boot/compressed/misc.c
, смотрите здесь: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
Сделайте подробное построение ядра и ищите файлы
Этот подход может дать некоторое представление, никогда не устареет и поможет вам легко определить, какая часть системы сборки делает что.
Если у вас есть конфигурация сборки, которая генерирует один из файлов, выполните сборку с помощью:
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"
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
Это все здесь: http://en.wikipedia.org/wiki/Vmlinux
vmlinux :
Несжатый и не загружаемый формат файла ядра Linux, просто промежуточный шаг к созданию vmlinuz
.
vmlinuz :
сжатый и загрузочный файл ядра Linux. Это на самом деле zImage
или bzImage
файл.
zImage :
Для старых ядер просто подгоните640k
размер оперативной памяти .
bzImage :,
Big zImage
без 640k
ограничения размера оперативной памяти , может гораздо больше.
Пожалуйста, обратитесь этот документ: vmlinuz Определение .
bzImage - цель, используемая для архитектур x86, работающих с BIOS компьютера. Напротив, zImage - это специфичная для архитектуры цель, наиболее часто используемая для встраиваемых устройств и хорошо работающая с их загрузчиками.