ข้อแตกต่างระหว่างเคอร์เนล Makefile ต่อไปนี้คืออะไร: vmLinux, vmlinuz, vmlinux.bin, zimage & bzimage?


50

ในขณะที่สืบค้น Kernel Makefiles ฉันพบคำศัพท์เหล่านี้ ดังนั้นผมจึงอยากจะรู้ว่าอะไรคือความแตกต่างระหว่างvmlinux, vmlinuz, vmlinux.bin, zimageและbzimage?


เกินมาตรฐานของฉันคิดว่า zimage เป็นการบีบอัด gz และ bzimage เป็นการบีบอัด bz ... การตั้งชื่อ jut, afaik ไม่มีความหมายอะไรเลย แต่ฉันอาจจะผิด
xenoterracide

นอกจากนี้ยังvmlinuz.efiใช้กับ Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
Ciro Santilli 新疆改造中心中心法轮功六四事件

คำตอบ:


59

vmlinux

นี่คือเคอร์เนล Linux ในรูปแบบไฟล์ปฏิบัติการที่ลิงก์แบบคงที่ โดยทั่วไปคุณไม่ต้องกังวลกับไฟล์นี้มันเป็นเพียงขั้นตอนกลางในขั้นตอนการบู๊ต

ไฟล์ vmlinux แบบ raw อาจมีประโยชน์สำหรับการดีบัก

vmlinux.bin

เหมือนกับ vmlinux แต่อยู่ในรูปแบบไฟล์ไบนารีที่สามารถบูตได้ สัญลักษณ์และข้อมูลการเปลี่ยนตำแหน่งทั้งหมดถูกทิ้ง ที่สร้างขึ้นจากจากvmlinuxobjcopy -O binary vmlinux vmlinux.bin

vmlinuz

แฟ้ม vmlinux zlibมักจะได้รับบีบอัดด้วย ตั้งแต่ 2.6.30 LZMAและbzip2ยังมีวางจำหน่าย โดยการเพิ่มความสามารถในการบูตและคลายการบีบอัดเพิ่มเติมไปยัง vmlinuz สามารถใช้อิมเมจเพื่อบู๊ตระบบด้วยเคอร์เนล vmlinux การบีบอัดของ vmlinux สามารถเกิดขึ้นได้กับ zImage หรือ bzImage

ฟังก์ชั่นนี้decompress_kernel()จะจัดการกับการคลายบีบอัดของ vmlinuz เมื่อทำการบูท, ข้อความระบุว่า:

Decompressing Linux... done
Booting the kernel.

zImage ( make zImage)

นี่เป็นรูปแบบเก่าสำหรับเมล็ดขนาดเล็ก (บีบอัดต่ำกว่า 512KB) เมื่อบูตภาพนี้มีหน่วยความจำเหลือน้อย (640KB แรกของ RAM)

bzImage ( make bzImage)

zImage ขนาดใหญ่ (ไม่มีส่วนเกี่ยวข้องbzip2) สร้างขึ้นในขณะที่เคอร์เนลโตขึ้นและจัดการรูปภาพที่ใหญ่กว่า (บีบอัดมากกว่า 512KB) ภาพได้รับการโหลดสูงในหน่วยความจำ (สูงกว่า RAM 1MB) เนื่องจากเมล็ดของวันนี้มีขนาดมากกว่า 512KB จึงเป็นวิธีที่ต้องการ


การตรวจสอบบน 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

อยู่ที่ไหนนี้decompress_kernel ()การดำเนินงานฟังก์ชั่นตั้งอยู่ที่ไหน?
Sen

2
มันอยู่ที่/arch/$ARCH/boot/compressed/misc.cดูที่นี่: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
กระดิก

8

ทำเคอร์เนล verbose สร้างและค้นหาไฟล์

วิธีการนี้สามารถให้ข้อมูลเชิงลึกบางอย่างไม่เคยล้าสมัยและจะช่วยให้คุณค้นหาว่าส่วนใดของระบบการสร้างกำลังทำอะไรอยู่

เมื่อคุณมีการกำหนดค่าการสร้างที่สร้างไฟล์ใดไฟล์หนึ่งให้สร้างด้วย:

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-lไลบรารี-to-other-static-lไลบรารี/27676016 # 27676016พวกเขาเป็นจดหมายเหตุที่เพิ่งชี้ไปที่จดหมายเหตุ / วัตถุอื่น ๆ แทนที่จะคัดลอกมัน

เคอร์เนลย้ายจากการเชื่อมโยงส่วนเพิ่มไปยังไฟล์เก็บถาวรแบบบางใน v4.9 ตามที่อธิบายไว้ที่: https://stackoverflow.com/questions/29391965/what-is-part--linking-in-gnu-linker/53959624#53959624

การตีความบันทึกอย่างเต็มรูปแบบ

เมื่อเราเริ่มอ่านบันทึกการสร้าง verbose จากการสำรองข้อมูลก่อนอื่นเราจะเห็น:

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

ดังนั้นเครื่องมือนี้จะต้องสร้าง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เป็นเพียงไฟล์ 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 ระบุไฟล์เก็บถาวรแบบ thin

จากนั้นเราจะเห็นได้ว่าคลังเก็บย่อยทั้งหมดนั้นบางเช่นกันตั้งแต่ฉันแก้ไข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ซึ่งประกอบด้วย

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



1

vmlinux :

vmlinuzรูปแบบที่ไม่บีบอัดและไม่สามารถบูตลินุกซ์เคอร์เนลไฟล์เพียงแค่ขั้นตอนกลางเพื่อการผลิต

vmlinuz :
ไฟล์เคอร์เนล Linux ที่สามารถบีบอัดและบูตได้ มันเป็นจริงzImageหรือbzImageไฟล์

zImage :
สำหรับเมล็ดเก่าให้พอดีกับ640kขนาดของ ram

bzImage :
Big zImageไม่640kจำกัด ขนาด ram สามารถใหญ่กว่านี้ได้มาก

โปรดดูเอกสารนี้vmlinuz นิยาม


1

bzImageเป็นเป้าหมายที่ใช้สำหรับสถาปัตยกรรม x86 ที่ทำงานกับ PC BIOS ในทางตรงกันข้ามzImageเป็นเป้าหมายเฉพาะสถาปัตยกรรมที่ใช้มากที่สุดสำหรับอุปกรณ์ฝังตัวและทำงานได้ดีกับ bootloaders ของพวกเขา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.