ในขณะที่สืบค้น Kernel Makefiles ฉันพบคำศัพท์เหล่านี้ ดังนั้นผมจึงอยากจะรู้ว่าอะไรคือความแตกต่างระหว่างvmlinux
, vmlinuz
, vmlinux.bin
, zimage
และbzimage
?
vmlinuz.efi
ใช้กับ Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
ในขณะที่สืบค้น Kernel Makefiles ฉันพบคำศัพท์เหล่านี้ ดังนั้นผมจึงอยากจะรู้ว่าอะไรคือความแตกต่างระหว่างvmlinux
, vmlinuz
, vmlinux.bin
, zimage
และbzimage
?
vmlinuz.efi
ใช้กับ Ubuntu 14.04: askubuntu.com/questions/330541/what-is-vmlinuz-efi
คำตอบ:
vmlinux
นี่คือเคอร์เนล Linux ในรูปแบบไฟล์ปฏิบัติการที่ลิงก์แบบคงที่ โดยทั่วไปคุณไม่ต้องกังวลกับไฟล์นี้มันเป็นเพียงขั้นตอนกลางในขั้นตอนการบู๊ต
ไฟล์ vmlinux แบบ raw อาจมีประโยชน์สำหรับการดีบัก
vmlinux.bin
เหมือนกับ vmlinux แต่อยู่ในรูปแบบไฟล์ไบนารีที่สามารถบูตได้ สัญลักษณ์และข้อมูลการเปลี่ยนตำแหน่งทั้งหมดถูกทิ้ง ที่สร้างขึ้นจากจากvmlinux
objcopy -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
/arch/$ARCH/boot/compressed/misc.c
ดูที่นี่: lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
ทำเคอร์เนล 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
ทุกอย่างอยู่ที่นี่: http://en.wikipedia.org/wiki/Vmlinux
vmlinux :
vmlinuz
รูปแบบที่ไม่บีบอัดและไม่สามารถบูตลินุกซ์เคอร์เนลไฟล์เพียงแค่ขั้นตอนกลางเพื่อการผลิต
vmlinuz :
ไฟล์เคอร์เนล Linux ที่สามารถบีบอัดและบูตได้ มันเป็นจริงzImage
หรือbzImage
ไฟล์
zImage :
สำหรับเมล็ดเก่าให้พอดีกับ640k
ขนาดของ ram
bzImage :
Big zImage
ไม่640k
จำกัด ขนาด ram สามารถใหญ่กว่านี้ได้มาก
โปรดดูเอกสารนี้vmlinuz นิยาม
bzImageเป็นเป้าหมายที่ใช้สำหรับสถาปัตยกรรม x86 ที่ทำงานกับ PC BIOS ในทางตรงกันข้ามzImageเป็นเป้าหมายเฉพาะสถาปัตยกรรมที่ใช้มากที่สุดสำหรับอุปกรณ์ฝังตัวและทำงานได้ดีกับ bootloaders ของพวกเขา