vmLinux, vmlinuz, vmlinux.bin, zimage 및 bzimage와 같은 커널 Makefile 용어의 차이점은 무엇입니까?


50

커널 Makefile을 탐색하는 동안이 용어를 찾았습니다. 그래서 차이점이 무엇인지 알고 싶습니다 vmlinux, vmlinuz, vmlinux.bin, zimage& bzimage?


zsize는 gz 압축이고 bzimage는 bz 압축이라고 생각합니다. 그러나 나는 틀릴 수 있었다.
xenoterracide

답변:


59

vmlinux

정적으로 링크 된 실행 파일 형식의 Linux 커널입니다. 일반적으로이 파일에 대해 걱정할 필요가 없으며 부팅 절차의 중간 단계 일뿐입니다.

원시 vmlinux 파일은 디버깅 목적으로 유용 할 수 있습니다.

vmlinux.bin

vmlinux와 동일하지만 부팅 가능한 원시 이진 파일 형식입니다. 모든 기호 및 재배치 정보가 삭제됩니다. 님이에서 생성 vmlinux했습니다 objcopy -O binary vmlinux vmlinux.bin.

vmlinuz

vmlinux 파일은 일반적으로로 압축됩니다 zlib. 2.6.30 이후 LZMAbzip2도 사용할 수 있습니다. vmlinuz에 부팅 및 압축 풀기 기능을 추가하면 이미지를 사용하여 vmlinux 커널로 시스템을 부팅 할 수 있습니다. vmlinux 압축은 zImage 또는 bzImage에서 발생할 수 있습니다.

이 기능 decompress_kernel()은 부팅시 vmlinuz 압축 해제를 처리합니다. 메시지는 다음을 나타냅니다.

Decompressing Linux... done
Booting the kernel.

z 이미지 ( 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

decompress_kernel () 함수 구현 은 어디에 있습니까 ?
Sen

2
그것은에 위치 /arch/$ARCH/boot/compressed/misc.c여기를 참조 : lxr.linux.no/#linux+v2.6.37/arch/x86/boot/compressed/...
흔들

8

자세한 커널 빌드를 수행하고 파일을 검색하십시오.

이 접근 방식은 통찰력을 제공하고 결코 최신 정보를 얻지 못하며 빌드 시스템의 어떤 부분이 무엇을하고 있는지 쉽게 찾을 수 있도록 도와줍니다.

파일 중 하나를 생성하는 빌드 구성이 있으면 다음을 사용하여 빌드하십시오.

make V=1 |& tee f.log

init/main.c이전에 이미 빌드 한 경우 일부 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에 언급되어 있습니다. 다른 아카이브 / 오브젝트를 복사하는 대신 가리 킵니다.

https : //.com/questions/29391965/what-is-partial-linking-in-gnu-linker/53959624#53959624에 설명 된대로 커널은 v4.9에서 증분 링크에서 씬 아카이브로 이동했습니다.

전체 로그 해석

백업에서 자세한 빌드 로그를 읽기 시작하면 먼저 다음을 볼 수 있습니다.

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.binTODO는 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 : //.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.

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 :

압축 및 부팅이 불가능한 Linux 커널 파일 형식으로, 중간 단계를 생성 vmlinuz합니다.

vmlinuz :
압축 및 부팅 가능한 Linux 커널 파일입니다. 실제로 zImage또는 bzImage파일입니다.

zImage :
오래된 커널의 경우 640k램 크기에 맞습니다 .

bzImage : 램 크기 제한이
Big zImage없으며 640k훨씬 더 클 수 있습니다.

이 문서를 참조하십시오 : vmlinuz Definition .


1

bzImage 는 PC BIOS와 함께 작동하는 x86 아키텍처에 사용되는 대상입니다. 반대로 zImage 는 임베디드 장치에 가장 일반적으로 사용되는 아키텍처 별 대상이며 부트 로더와 잘 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.