GNU/Linux >> Belajar Linux >  >> Linux

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

vmlinux

Ini adalah kernel Linux dalam format file yang dapat dieksekusi yang terhubung secara statis. Secara umum, Anda tidak perlu khawatir tentang file ini, ini hanyalah langkah perantara dalam prosedur booting.

File vmlinux mentah mungkin berguna untuk tujuan debugging.

vmlinux.bin

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

vmlinuz

File vmlinux biasanya dikompres dengan zlib . Sejak 2.6.30 LZMA dan bzip2 juga tersedia. Dengan menambahkan kemampuan boot dan dekompresi lebih lanjut ke vmlinuz, image dapat digunakan untuk mem-boot sistem dengan kernel vmlinux. Kompresi vmlinux dapat terjadi dengan zImage atau bzImage.

Fungsi decompress_kernel() menangani dekompresi vmlinuz saat boot, sebuah pesan menunjukkan ini:

Decompressing Linux... done
Booting the kernel.

zGambar (make zImage )

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

bzImage (make bzImage )

ZImage besar (ini tidak ada hubungannya dengan bzip2 ), dibuat saat kernel tumbuh dan menangani gambar yang lebih besar (dikompresi, lebih dari 512KB). Gambar dimuat dalam memori tinggi (di atas 1MB RAM). Karena kernel saat ini berukuran lebih dari 512KB, ini biasanya cara yang lebih 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 ([email protected], RO-rootFS, root_dev 0x6801, swap_dev 0x4, Normal VGA

Lakukan pembuatan kernel verbose dan cari file

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

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

make V=1 |& tee f.log

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

Sekarang, periksa f.log dan telusuri gambar yang menarik.

Misalnya, pada v4.19 kami 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 Itu adalah arsip yang hanya menunjukkan arsip / objek lain alih-alih menyalinnya.

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

Interpretasi log lengkap

Saat kita mulai membaca log build verbose dari cadangan, pertama-tama kita melihat:

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

jadi keduanya hanya disinkronkan.

Kemudian kita mencari sedikit lebih jauh untuk x86/boot/bzImage dan temukan:

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 menjalankannya, 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/bzImage dari arch/x86/boot/vmlinux.bin dan file lain TODO apa gunanya build tepatnya?

Jika kita mengikuti arch/x86/boot/vmlinux.bin kita melihat bahwa itu hanyalah sebuah objcopy dari 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/vmlinux hanyalah 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 -hlSr mengatakan bahwa piggy.o sejauh ini merupakan 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.

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

.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 berasal 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 berfungsi:

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 sangat besar, tetapi semua objek yang ditampilkan kecil menurut ls -l , jadi saya meneliti dan mempelajari tentang ar yang baru fitur yang tidak saya ketahui:arsip tipis.

Di:

AR      built-in.a

build melakukan:

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, sejak saya memodifikasi 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.o ke init/main.o menginjak log yang memalukan... dengan:

git grep '\.tmp_'

kami melihat bahwa kemungkinan berasal dari scripts Makefile.build dan ditautkan ke CONFIG_MODVERSIONS yang telah saya aktifkan:

ifndef CONFIG_MODVERSIONS
cmd_cc_o_c = $(CC) $(c_flags) -c -o [email protected] $<

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 [email protected] $(@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) [email protected];                  \
    fi;
endif

Analisis dilakukan dengan konfigurasi ini yang berisi CONFIG_KERNEL_GZIP=y .

aarch64 arch/arm64/boot/Image

Hanya objcopy yang tidak terkompresi dari 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 persis sama seperti untuk x86 melalui arsip tipis.

arch/arm/boot/zImage

Sangat mirip dengan X86 dengan zip vmlinux , tapi bukan build.c ajaib melangkah. 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 mem-boot dari bzImage tetapi tidak dari vmlinux

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


Linux
  1. Apa perbedaan antara module_init dan init_module dalam modul kernel Linux?

  2. Apa perbedaan antara strtok_r dan strtok_s di C?

  3. Apa perbedaan antara fsck dan e2fsck?

  1. Apa perbedaan antara driver kernel dan modul kernel?

  2. Apa perbedaan antara `su -` dan` su --login`?

  3. Apa perbedaan antara partx dan kpartx?

  1. Apa perbedaan antara #!/usr/bin/env bash dan #!/usr/bin/bash?

  2. apa perbedaan antara remount ke umount/mount?

  3. Apa perbedaan antara unlink dan rm?