vmLinux、vmlinuz、vmlinux.bin、zimage、bzimageなどのカーネルMakefile用語の違いは何ですか?

vmLinux、vmlinuz、vmlinux.bin、zimage、bzimageなどのカーネルMakefile用語の違いは何ですか?

カーネルのMakefileを探索する際に、これらの用語を見つけました。だから、、、、vmlinux&の違いが何であるかを知りたいvmlinuzです。vmlinux.binzimagebzimage

答え1

仮想マシンLinux

これはLinuxカーネルの静的にリンクされた実行可能ファイル形式です。一般的に言えば、このファイルについて心配する必要はありません。これは起動プロセスの中間段階です。

ネイティブvmlinuxファイルはデバッグ目的で役に立ちます。

仮想マシンlinux.bin

vmlinuxと同じですが、起動可能な生のバイナリ形式です。すべてのシンボルおよび再配置情報は削除されます。vmlinuxによって生成されたobjcopy -O binary vmlinux vmlinux.bin

仮想デバイス

vmlinuxファイルは通常使用されます。zlib2.6.30から利用可能LZMAですbzip2。 vmlinuzに起動および解凍機能を追加すると、このイメージを使用してvmlinuxカーネルを含むシステムを起動できます。 vmlinuxの圧縮はzImageまたはbzImageを介して実行できます。

この関数はdecompress_kernel()起動時にvmlinuzの解凍を処理し、次のメッセージが表示されます。

Decompressing Linux... done
Booting the kernel.

ジイメージ( make zImage)

これは小さなカーネル(圧縮、512KB未満)の以前の形式です。起動時に、イメージはサブメモリ(RAMの最初の640 KB)にロードされます。

bz画像( make bzImage)

bzip2カーネルが成長し、より大きな画像(圧縮された512 KB以上)を処理すると、大きなzImage(これには関係ありません)が生成されます。画像は大容量メモリ(1 MB RAM以上)にロードされます。今日のカーネルは512 KBよりはるかに大きいので、通常この方法が好まれます。


Ubuntu 10.10を確認すると、次のようになります。

ls -lh /boot/vmlinuz-$(uname -r)
-rw-r--r-- 1 root root 4.1M 2010-11-24 12:21 /boot/vmlinuz-2.6.35-23-generic

file /boot/vmlinuz-$(uname -r)
/boot/vmlinuz-2.6.35-23-generic: Linux kernel x86 boot executable bzImage, version 2.6.35-23-generic (buildd@rosea, RO-rootFS, root_dev 0x6801, swap_dev 0x4, Normal VGA

答え2

詳細なカーネルの構築とファイル検索の実行

このアプローチは、決してスタイルを逸脱しない洞察を提供し、ビルドシステムのどの部分が何をしているのかを簡単に見つけるのに役立ちます。

これらのファイルのいずれかを生成するビルド構成がある場合は、次のコマンドを使用してビルドします。

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では、カーネルは次のように増分リンクからシンアーカイブに移動しました。https://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker/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それでは、他のファイルからTODOを生成する必要があるこのツールarch/x86/boot/vmlinux.binのポイントは正確に何ですかbuild

フォローすると、次arch/x86/boot/vmlinux.binの内容であることがわかります。objcopyarch/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/vmlinuxELFファイル:

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

分析完了この構成含まれていますCONFIG_KERNEL_GZIP=y

建築 64arch/arm64/boot/Image

ただ解凍objcopyvmlinux

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

答え3

私は通常このようなことを理解するためにウィキペディアを使用しませんが、仮想マシンLinux

Linuxカーネルが成熟するにつれて、ユーザー生成カーネルのサイズは、圧縮カーネルコードを格納するために使用できるスペースが限られているいくつかのアーキテクチャによって課される制限を超えています。 bzImage(big zImage)形式は、カーネルを個々のメモリ領域に分割することによってこれらの制限を克服するために開発されました。

bzImage は Linux 2.6.30 まで圧縮に gzip を使用します。

bzImageファイルは特定の形式になっています。 bootsect.o + setup.o + Misc.o + Piggy.oが接続されて含まれています。 Piggy.oのデータセクションには、gzipで圧縮されたvmlinuxファイルが含まれています。

ここに画像の説明を入力してください。

私は質問の一部だけに答えたことを知っています。私はまだそれを理解しようとしています。

答え4

bz画像PC BIOS で使用される x86 アーキテクチャのターゲットです。対照的に、ジイメージ組み込みデバイスで最も一般的に使用されるアーキテクチャ固有のターゲットであり、ブートローダとうまく機能します。

関連情報