커널 Makefile을 탐색하는 동안 이러한 용어를 발견했습니다. 그래서 vmlinux
, vmlinuz
, vmlinux.bin
, & zimage
의 차이점이 무엇인지 알고 싶습니다 bzimage
.
답변1
가상 머신Linux
이는 Linux 커널의 정적으로 링크된 실행 파일 형식입니다. 일반적으로 말하면 이 파일에 대해 걱정할 필요가 없습니다. 이는 부팅 프로세스의 중간 단계일 뿐입니다.
원시 vmlinux 파일은 디버깅 목적으로 유용할 수 있습니다.
가상 머신 linux.bin
vmlinux와 동일하지만 부팅 가능한 원시 바이너리 형식입니다. 모든 기호 및 재배치 정보는 삭제됩니다. vmlinux
에 의해 생성 된 objcopy -O binary vmlinux vmlinux.bin
.
가상 기기
vmlinux 파일은 일반적으로 사용됩니다 . zlib
2.6.30부터 사용 가능 LZMA
합니다 bzip2
. vmlinuz에 부팅 및 압축 해제 기능을 추가하면 이 이미지를 vmlinux 커널이 있는 시스템을 부팅하는 데 사용할 수 있습니다. vmlinux의 압축은 zImage 또는 bzImage를 통해 수행할 수 있습니다.
이 함수는 decompress_kernel()
시작 시 vmlinuz의 압축 해제를 처리하며 다음과 같은 메시지가 표시됩니다.
Decompressing Linux... done
Booting the kernel.
지이미지( make zImage
)
이것은 작은 커널(압축, 512KB 미만)의 이전 형식입니다. 시작 시 이미지는 하위 메모리(RAM의 첫 번째 640KB)에 로드됩니다.
bz이미지( make bzImage
)
bzip2
커널이 성장하고 더 큰 이미지(압축된 512KB 이상)를 처리하면 큰 zImage(이는 이와 관련이 없음 )가 생성됩니다. 이미지는 고용량 메모리(1MB RAM 이상)에 로드됩니다. 오늘날의 커널은 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
답변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
따라서 이 둘은 단지 심볼릭 링크일 뿐입니다.
그런 다음 추가 검색을 통해 다음을 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
과 같은 내용임을 알 수 있습니다 .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"
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
.
건축 64arch/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
답변3
나는 보통 이와 같은 것을 이해하기 위해 Wikipedia를 사용하지 않지만,가상 머신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 아키텍처의 대상입니다. 대조적으로,지이미지임베디드 장치에 가장 일반적으로 사용되는 아키텍처별 타겟이며 부트로더와 잘 작동합니다.