एक वर्बोज़ कर्नेल बनाएँ और फ़ाइलों की खोज करें
यह दृष्टिकोण कुछ अंतर्दृष्टि दे सकता है, कभी भी बाहर नहीं निकलेगा, और आपको आसानी से यह पता लगाने में मदद करेगा कि निर्माण प्रणाली का कौन सा हिस्सा क्या कर रहा है।
एक बार आपके पास बिल्ड कॉन्फ़िगरेशन होता है जो फ़ाइलों में से एक उत्पन्न करता है, इसके साथ निर्माण करें:
make V=1 |& tee f.log
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-lbooks-to-other-static-lbooks/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
तो यह उपकरण TODO और अन्य फाइलों arch/x86/boot/bzImageसे उत्पन्न होना चाहिए arch/x86/boot/vmlinux.binकि 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बस एक नियमित ईएलएफ फ़ाइल है:
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"
इसे भी देखें: https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc/36295692#36295692
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
जो अंत में सी फाइल से एक कमांड के माध्यम से आता है जैसे:
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