Thực hiện xây dựng nhân dài dòng và tìm kiếm các tệp
Cách tiếp cận này có thể cung cấp một số cái nhìn sâu sắc, sẽ không bao giờ lỗi thời và sẽ giúp bạn dễ dàng tìm thấy phần nào của hệ thống xây dựng đang làm gì.
Khi bạn có cấu hình bản dựng tạo một trong các tệp, hãy tạo với:
make V=1 |& tee f.log
Sửa đổi nhận xét về một số tệp C để buộc liên kết lại (ví dụ: init/main.cmột liên kết tốt) nếu bạn đã xây dựng trước đó.
Bây giờ, kiểm tra f.logvà tìm kiếm những hình ảnh quan tâm.
Ví dụ, vào v4.19, chúng tôi sẽ kết luận rằng:
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
Tài liệu lưu trữ mỏng được đề cập tại: https://stackoverflow.com/questions/2157629/linking-static-lologists-to-other-static-lologists/27676016#27676016 Chúng là những tài liệu lưu trữ chỉ trỏ các tài liệu lưu trữ / đối tượng khác thay vì sao chép chúng.
Hạt nhân đã chuyển từ liên kết gia tăng sang tài liệu lưu trữ mỏng trong v4.9 như được mô tả tại: https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624
Giải thích nhật ký đầy đủ
Khi chúng ta bắt đầu đọc nhật ký xây dựng dài dòng từ bản sao lưu, đầu tiên chúng ta sẽ thấy:
ln -fsn ../../x86/boot/bzImage ./arch/x86_64/boot/bzImage
vì vậy hai cái đó chỉ là liên kết với nhau
Sau đó, chúng tôi tìm kiếm thêm một chút cho x86/boot/bzImagevà tìm:
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 là một tệp thực thi, vì vậy chúng tôi chạy nó, xem thông báo trợ giúp:
Usage: build setup system zoffset.h image
và grep để tìm nguồn:
arch/x86/boot/tools/build.c
Vì vậy, công cụ này phải được tạo arch/x86/boot/bzImagetừ arch/x86/boot/vmlinux.binvà các tệp khác TODO điểm buildchính xác là gì?
Nếu chúng tôi theo dõi, arch/x86/boot/vmlinux.binchúng tôi thấy rằng đó chỉ là một objcopytừ arch/x86/boot/compressed/vmlinux:
objcopy \
-O binary \
-R .note \
-R .comment \
-S arch/x86/boot/compressed/vmlinux \
arch/x86/boot/vmlinux.bin
và arch/x86/boot/compressed/vmlinuxchỉ là một tệp ELF thông thường:
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 -hlSrnói rằng đó piggy.olà tập tin lớn nhất, vì vậy chúng tôi tìm kiếm nó và nó phải đến từ:
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_ tiền tố giải thích dưới đây.
arch/x86/boot/compressed/piggy.S chứa đựng:
.incbin "arch/x86/boot/compressed/vmlinux.bin.gz"
xem thêm: https://stackoverflow.com/questions/4158900/embpping-resource-in-executable-USE-gcc/36295692#36295692
arch/x86/boot/compressed/vmlinux.bin.gz đến từ:
cat arch/x86/boot/compressed/vmlinux.bin arch/x86/boot/compressed/vmlinux.relocs | \
gzip -n -f -9 > arch/x86/boot/compressed/vmlinux.bin.gz
xuất phát từ:
objcopy -R .comment -S vmlinux arch/x86/boot/compressed/vmlinux.bin
xuất phát từ:
LD vmlinux
cái nào:
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
vmlinuxlà rất lớn, nhưng tất cả các đối tượng được hiển thị đều nhỏ bé ls -l, vì vậy tôi đã nghiên cứu và tìm hiểu về một artính năng mới mà tôi không biết: lưu trữ mỏng.
Tại:
AR built-in.a
bản dựng không:
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 chỉ định lưu trữ mỏng.
Sau đó chúng ta có thể thấy rằng tất cả các tài liệu lưu trữ phụ cũng mỏng, ví dụ, kể từ khi tôi sửa đổi init/main.c, chúng ta 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
mà cuối cùng xuất phát từ tệp C thông qua một lệnh như:
gcc \
-Wp,-MD,init/.main.o.d \
-c \
-o \
init/.tmp_main.o \
/work/linux-kernel-module-cheat/submodules/linux/init/main.c
Tôi không thể tìm ra init/.tmp_main.ođể init/main.obước vào các bản ghi đó là một sự xấu hổ ... với:
git grep '\.tmp_'
chúng tôi thấy rằng có khả năng đến từ scripts Makefile.buildvà được liên kết với CONFIG_MODVERSIONSmà tôi đã kích hoạt:
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
Phân tích được thực hiện với cấu hình này có chứa CONFIG_KERNEL_GZIP=y.
aarch64 arch/arm64/boot/Image
Chỉ là một giải nén objcopytừ vmlinux:
objcopy -O binary -R .note -R .note.gnu.build-id -R .comment -S vmlinux arch/arm64/boot/Image
vmlinux về cơ bản được lấy theo cách chính xác giống như đối với x86 mặc dù tài liệu lưu trữ mỏng.
arch/arm/boot/zImage
Rất giống với X86 với khóa kéo vmlinux, nhưng không có build.cbước ma thuật . Tóm tắt chuỗi cuộc gọi:
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 có thể khởi động từ bzImage nhưng không phải vmlinux
Đây là một sự khác biệt thực tế quan trọng khác: https://superuser.com/questions/1451568/boote-an-uncompression-kernel-in-qemu