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