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