Apa perbedaan antara istilah-istilah Makefile kernel berikut: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?

50

Saat browsing melalui Kernel Makefiles, saya menemukan istilah-istilah ini. Jadi saya ingin tahu apa perbedaan antara vmlinux, vmlinuz, vmlinux.bin, zimage& bzimage?

Sen
sumber
outsize dari saya pikir zimage adalah kompresi gz dan bzimage adalah kompresi bz ... hanya penamaan, afaik tidak ada yang berarti apa-apa. tapi saya bisa saja salah.
xenoterracide
Ada juga yang vmlinuz.efidigunakan pada Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

59

vmlinux

Ini adalah kernel Linux dalam format file yang dapat dieksekusi yang terhubung secara statis. Secara umum, Anda tidak perlu khawatir tentang file ini, itu hanya langkah menengah dalam prosedur boot.

File raw vmlinux mungkin berguna untuk keperluan debugging.

vmlinux.bin

Sama seperti vmlinux, tetapi dalam format file biner mentah yang dapat di-boot. Semua simbol dan informasi relokasi dibuang. Dihasilkan dari vmlinuxoleh objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

File vmlinux biasanya dikompresi zlib. Sejak 2.6.30 LZMAdan bzip2juga tersedia. Dengan menambahkan kemampuan boot dan dekompresi lebih lanjut ke vmlinuz, gambar dapat digunakan untuk mem-boot sistem dengan kernel vmlinux. Kompresi vmlinux dapat terjadi dengan zImage atau bzImage.

Fungsi ini decompress_kernel()menangani dekompresi vmlinuz saat bootup, sebuah pesan mengindikasikan ini:

Decompressing Linux... done
Booting the kernel.

zGambar ( make zImage)

Ini adalah format lama untuk kernel kecil (terkompresi, di bawah 512KB). Saat boot, gambar ini dimuat dalam memori rendah (RAM 640KB pertama).

bzImage ( make bzImage)

ZImage besar (ini tidak ada hubungannya dengan bzip2), diciptakan ketika kernel tumbuh dan menangani gambar yang lebih besar (terkompresi, lebih dari 512KB). Gambar dimuat dalam memori tinggi (di atas 1MB RAM). Karena kernel saat ini adalah lebih dari 512KB, ini biasanya cara yang disukai.


Inspeksi pada Ubuntu 10.10 menunjukkan:

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
mengibaskan
sumber
Di mana implementasi fungsi decompress_kernel () ini berada?
Sen
2
Hal ini terletak di /arch/$ARCH/boot/compressed/misc.c, lihat di sini: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
wag
8

Lakukan pembuatan kernel verbose dan cari file

Pendekatan ini dapat memberikan beberapa wawasan, tidak akan pernah ketinggalan zaman, dan akan membantu Anda untuk dengan mudah menemukan bagian mana dari sistem build yang melakukan apa.

Setelah Anda memiliki konfigurasi build yang menghasilkan salah satu file, build with:

make V=1 |& tee f.log

Ubah komentar pada beberapa file C untuk memaksa tautan ulang (mis. Yang init/main.cbagus) jika Anda sudah membangun sebelumnya.

Sekarang, periksa f.logdan cari gambar yang menarik.

Sebagai contoh, pada v4.19 kita akan menyimpulkan bahwa:

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

Arsip tipis disebutkan di: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries/27676016#27676016 Ini adalah arsip yang hanya menunjuk arsip / objek lain alih-alih menyalinnya.

Kernel bergerak dari penautan bertahap ke arsip tipis di v4.9 seperti dijelaskan di: https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624

Interpretasi log lengkap

Ketika kita mulai membaca log build verbose dari belakang, pertama-tama kita melihat:

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

jadi keduanya hanya disinkronkan.

Kemudian kami mencari sedikit lebih jauh x86/boot/bzImagedan menemukan:

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 dapat dieksekusi, jadi kami jalankan, lihat pesan bantuan:

Usage: build setup system zoffset.h image

dan grep untuk menemukan sumbernya:

arch/x86/boot/tools/build.c

Jadi alat ini harus menghasilkan arch/x86/boot/bzImagedari arch/x86/boot/vmlinux.bindan file-file lain TODO apa gunanya buildsebenarnya?

Jika kita mengikuti, arch/x86/boot/vmlinux.binkita melihat bahwa itu hanya objcopydari arch/x86/boot/compressed/vmlinux:

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

dan arch/x86/boot/compressed/vmlinuxini hanya file ELF biasa:

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 -hlSrmengatakan itu piggy.oadalah file terbesar, jadi kami mencarinya, dan itu harus berasal dari:

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_ awalan dijelaskan di bawah ini.

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

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

lihat juga: https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc/36295692#36295692

arch/x86/boot/compressed/vmlinux.bin.gz datang dari:

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

yang berasal dari:

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

yang berasal dari:

LD      vmlinux

yang tidak:

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

vmlinuxmemang besar, tetapi semua objek yang ditampilkan kecil menurut ls -l, jadi saya meneliti dan mempelajari arfitur baru yang tidak saya ketahui: arsip tipis.

Di:

AR      built-in.a

build tidak:

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 menentukan arsip tipis.

Kita kemudian dapat melihat bahwa semua sub arsip juga tipis, misalnya, karena saya modifikasi init/main.c, kami memiliki:

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

yang akhirnya berasal dari file C melalui perintah seperti:

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

Saya tidak dapat menemukan init/.tmp_main.ountuk init/main.omenginjak log yang memalukan ... dengan:

git grep '\.tmp_'

kami melihat bahwa kemungkinan berasal dari scripts Makefile.builddan terhubung dengan CONFIG_MODVERSIONSyang telah saya aktifkan:

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

Analisis dilakukan dengan konfigurasi ini yang berisi CONFIG_KERNEL_GZIP=y.

aarch64 arch/arm64/boot/Image

Hanya yang tidak dikompresi objcopydari vmlinux:

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

vmlinux diperoleh pada dasarnya dengan cara yang sama persis seperti untuk x86 meskipun arsip tipis.

arch/arm/boot/zImage

Sangat mirip dengan X86 dengan zip vmlinux, tetapi tidak ada build.clangkah ajaib . Ringkasan rantai panggilan:

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 dapat melakukan boot dari bzImage tetapi tidak vmlinux

Ini adalah perbedaan praktis penting lainnya: https://superuser.com/questions/1451568/booting-an-uncompressed-kernel-in-qemu

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

vmlinux :

Format file kernel Linux non-terkompresi dan non-boot, hanya langkah menengah untuk memproduksi vmlinuz.

vmlinuz :
File kernel Linux yang terkompresi dan dapat di-boot. Sebenarnya zImageatau bzImagefile.

zImage :
Untuk kernel lama, pas 640kukuran ram.

bzImage :
Big zImage, tidak ada 640kram batas ukuran, banyak yang dapat lebih besar.

Silakan merujuk dokumen ini: Definisi vmlinuz .

Nan Xiao
sumber
1

bzImage adalah target yang digunakan untuk arsitektur x86 yang bekerja dengan PC BIOS. Sebaliknya, zImage adalah target spesifik arsitektur yang paling umum digunakan untuk perangkat tertanam dan bekerja dengan baik dengan bootloader mereka.

Behnam Dezfouli
sumber