質問: 次のカーネルmakefile用語の違いは何ですか:vmlinux、vmlinuz、vmlinux.bin、zimage&bzimage? カーネルmakefileを閲覧しているときに、これらの用語を見つけました。 vmlinux、vmlinuz、vmlinux.bin、zimageとbzimageの違いは何ですか?
回答: 詳細なカーネルビルドを実行し、ファイルを検索しますこのアプローチは、ある程度の洞察を提供し、決して古くなることはなく、ビルドシステムのどの部分が何をしているかを簡単に見つけるのに役立ちます。ファイルの1つを生成するビルド構成を作成したら、次のコマンドでビルドします。make v=1 |& tee f.log 以前にビルドしたことがある場合は、一部のcファイルのコメントを変更して、強制的に再リンクします(例: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-libraries-to-other-static-libraries/27676016#27676016 それらはアーカイブですそれらをコピーするのではなく、他のアーカイブ/オブジェクトをポイントするだけです。 で説明されているように、カーネルはv4.9のインクリメンタルリンクからシンアーカイブに移動しました: 53959624#53959624 完全なログ解釈詳細なビルドログをバックアップから読み取り始めると、最初に次のことがわかります。ln -fsn ../../x86/boot/bzimage ./arch/x86_64/boot/bzimage したがって、これら2つはシンボリックリンクされています。次に、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 したがって、このツールはarch/x86/boot/bzimageおよび他のファイルからarch/x86/boot/vmlinux.binを生成する必要がありますtodo buildのポイントは正確に何ですか?arch/x86/boot/vmlinux.binをフォローすると、arch/x86/boot/compressed/vmlinuxからのobjcopyにすぎないことがわかります。objcopy \ -o binary \ -r .note \ -r .comment \ -s arch/x86/boot/compressed/vmlinux \ arch/x86/boot/vmlinux.bin arch/x86/boot/compressed/vmlinuxは通常のelfファイルです。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 最終的には、次のようなコマンドを介してcファイルから取得されます。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 分析は this config を含み、config_kernel_gzip=yを含みます。aarch64 arch/arm64/boot/imageobjcopyの圧縮されていない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圧縮されたvmlinuxを備えたx86に非常に似ていますが、魔法の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