एक वर्बोज़ कर्नेल बनाएँ और फ़ाइलों की खोज करें
यह दृष्टिकोण कुछ अंतर्दृष्टि दे सकता है, कभी भी बाहर नहीं निकलेगा, और आपको आसानी से यह पता लगाने में मदद करेगा कि निर्माण प्रणाली का कौन सा हिस्सा क्या कर रहा है।
एक बार आपके पास बिल्ड कॉन्फ़िगरेशन होता है जो फ़ाइलों में से एक उत्पन्न करता है, इसके साथ निर्माण करें:
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