close

 

一直以來都有一個困惑到底 bzImage 是由什麼東西所組成的呢? 稍微 trace 了一下 kernel, 雖然還是一大堆困惑 -_-

在 kernel source 的最上層 make V=1 &> make.proc, 可以看到整個 build 的詳細過程. 稍微整理了一下如下所示

vmlinux-img.png

Step 1 - 之前的是 kernel 本尊 ( vmlinux ) 保留了 .note, .comment, 和除錯資訊, 藉由 objcopy  -R .comment -S vmlinux arch/x86/boot/compressed/vmlinux.bin 去除了 .commnt和除錯資訊 產出了 vmlinux.bin, 這個就是沒有壓縮前的 kernel

Step 2 - gzip -f -9 < arch/x86/boot/compressed/vmlinux.bin > arch/x86/boot/compressed/vmlinux.bin.gz

Step 3 - ld -m elf_i386   -r --format binary --oformat elf32-i386 -T arch/x86/boot/compressed/vmlinux.scr arch/x86/boot/compressed/vmlinux.bin.gz -o arch/x86/boot/compressed/piggy.o

透過 linker script file - vmlunux.scr 將壓縮過後的核心本尊置放於 .rodata.compressed 節區 (目前只知道這樣子), 產出為 piggy.o

Step 4 - ld -m elf_i386   -T arch/x86/boot/compressed/vmlinux_32.lds arch/x86/boot/compressed/head_32.o arch/x86/boot/compressed/misc.o arch/x86/boot/compressed/piggy.o -o arch/x86/boot/compressed/vmlinux, 分別將 head_32.o, misc.o, piggy.o 打包成 vmlinux

Step 5 -

gcc -Wp,-MD,arch/x86/boot/.header.o.d  -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.3.2/include -Iinclude  -I/usr/src/linux-2.6.30    /linux-2.6.30/arch/x86/include -include include/linux/autoconf.h -D__KERNEL__ -Iinclude  -I/usr/src/linux-2.6.30/linux-2.6.30/arch/x86/i    nclude -include include/linux/autoconf.h -g -Os -D_SETUP -D__KERNEL__ -DDISABLE_BRANCH_PROFILING -Wall -Wstrict-prototypes -march=i386 -    mregparm=3 -include /usr/src/linux-2.6.30/linux-2.6.30/arch/x86/boot/code16gcc.h -fno-strict-aliasing -fomit-frame-pointer  -ffreestandi    ng  -fno-toplevel-reorder  -fno-stack-protector  -mpreferred-stack-boundary=2  -m32 -D__ASSEMBLY__   -DSVGA_MODE=NORMAL_VGA -Iarch/x86/boot  -c -o arch/x86/boot/header.o arch/x86/boot/header.S

gcc -Wp,-MD,arch/x86/boot/.version.o.d  -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.3.2/include -Iinclude  -I/usr/src/linux-2.6.3    0/linux-2.6.30/arch/x86/include -include include/linux/autoconf.h -D__KERNEL__ -Iinclude -I/usr/src/linux-2.6.30/linux-2.6.30/arch/x86/i    nclude -include include/linux/autoconf.h -g -Os -D_SETUP -D__KERNEL__ -DDISABLE_BRANCH_PROFILING -Wall -Wstrict-prototypes -march=i386 -    mregparm=3 -include /usr/src/linux-2.6.30/linux-2.6.30/arch/x86/boot/code16gcc.h -fno-strict-aliasing -fomit-frame-pointer -ffreestandin    g -fno-toplevel-reorder -fno-stack-protector -mpreferred-stack-boundary=2 -m32   -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(version)"  -D"KBUILD_MODNAME=KBUILD_STR(version)"  -c -o arch/x86/boot/.tmp_version.o arch/x86/boot/version.c

ld -m elf_i386   -T arch/x86/boot/setup.ld arch/x86/boot/a20.o arch/x86/boot/cmdline.o arch/x86/boot/copy.o arch/x86/boot/cpu.o arch/x86/boot/cpucheck.o arch/x86/boot/edd.o arch/x86/boot/header.o arch/x86/boot/main.o arch/x86/boot/mca.o arch/x86/boot/memory.o arch/x86/boot/pm.o arch/x86/boot/pmjump.o arch/x86/boot/printf.o arch/x86/boot/string.o arch/x86/boot/tty.o arch/x86/boot/video.o arch/x86/boot/video-mode.o arch/x86/boot/version.o arch/x86/boot/video-vga.o arch/x86/boot/video-vesa.o arch/x86/boot/video-bios.o -o arch/x86/boot/setup.elf

// 上面很明顯的看到是 build 一些關於 vga 還有一些架構相關的一些開機檔

objcopy  -O binary arch/x86/boot/setup.elf arch/x86/boot/setup.bin

objcopy  -O binary -R .note -R .comment -S arch/x86/boot/compressed/vmlinux arch/x86/boot/vmlinux.bin

arch/x86/boot/tools/build arch/x86/boot/setup.bin arch/x86/boot/vmlinux.bin CURRENT > arch/x86/boot/bzImage

最後透過 build command 將 steup.bin和vmlinux.bin 整合成 bzImage, 如此就構成了整個核心的鏡像。

我們常在開機時會看到 Decompressing Linux...這個竟究是在哪邊做的呢?其實就是圖中的misc.o中, 核心 support 三個壓縮的方法,default 是用gzip, 另外還有 bzip2, 和 lzma, 可以在 arch/x86/boot/compressed/misc.c 一探究竟.

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 sakbk 的頭像
    sakbk

    sakbk

    sakbk 發表在 痞客邦 留言(2) 人氣()