2.4. bzImage가 만들어지는 과정 추적-Log 분석

2.4.1. make bzImage 순서 정리

make bzimage를 실행 했을 때 실행되는 순서를 Makefile을 기준으로 나열해 봤다.

  1. $(TOPDIR)/Makefile에 포함된 $(TOPDIR)/arch/i386/Makefile에 있는 'bzimage:'로부터 시작

  2. 의존 관계에 의해 vmlinux가 먼저 만들어짐

    이때 vmlinux가 만들어지면 $(TOPDIR)/arch/i386/boot로 이동해 계속 진행

  3. vmlinux의 진행

    의존 관계에 의해 version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs가 먼저 만들어짐

  4. 의존 관계에 의한 만들기가 끝나면 $(TOPDIR)/vmlinux가 만들어짐

  5. 의존 관계에 의해 $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build가 만들어진다

  6. compressed/bvmlinux의 진행

    의존 관계에 의해 piggy.o $(OBJECTS)가 먼저 만들어짐

  7. piggy.o는 $(TOPDIR)/vmlinux를 압축해 만든다.

순서대로 나열했지만 Makefile의 특성상 하나를 만들기 전에 이미 다른 것이 먼저 만들어져야하는 등의 의존 관계가 있기 때문에 순서가 뒤집힌 것처럼 보일 것이다. 이를 바로 잡아 먼저 만들어지는 순으로 나열해보면 아래와 같다.

  1. vmlinux

    1. include/linux/version.h

    2. init/main.o

    3. init/version.o

    4. linuxsubidrs(fs lib mm ipc kernel drivers net)

  2. bzimage

    1. bbootsect

    2. bsetup

    3. compressed/bvmlinux

      1. piggy.o

      2. head.o

      3. misc.o

    4. tools/build

2.4.2. Log

Makefile을 통해 분석된 것을 이제는 실예를 사용해 분석해보자. 아래 Log는 'make bzImage 2>&1 | tee log-bzImage.txt'를 사용해 얻은 것이다. 전체는 필요 없는 부분이 너무 많기 때문에 필요 없는 부분은 삭제하거나 축약하고 실었다.

(1)
gcc -D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4    -c -o init/main.o init/main.c
. scripts/mkversion > .tmpversion

(2)
gcc -D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4   -DUTS-MACHINE='"i386"' -c -o init/version.o init/version.c
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  kernel

(3)
gcc -D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4   -DUTS-MACHINE='"i386"' -c -o init/version.o init/version.c
make[1]: 들어감 `/usr/src/linux-2.4.16/kernel' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/kernel' 디렉토리
rm -f kernel.o
ld -m elf-i386  -r -o kernel.o sched.o dma.o fork.o exec-domain.o panic.o printk.o module.o exit.o itimer.o info.o time.o softirq.o resource.o sysctl.o acct.o capability.o ptrace.o timer.o user.o signal.o sys.o kmod.o context.o uid16.o ksyms.o pm.o
make[2]: 나감 `/usr/src/linux-2.4.16/kernel' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/kernel' 디렉토리

(4)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  drivers
make[1]: 들어감 `/usr/src/linux-2.4.16/drivers' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/drivers' 디렉토리

(5)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  mm
make[1]: 들어감 `/usr/src/linux-2.4.16/mm' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/mm' 디렉토리
rm -f mm.o
ld -m elf-i386  -r -o mm.o memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o vmalloc.o slab.o bootmem.o swap.o vmscan.o page-io.o page-alloc.o swap-state.o swapfile.o numa.o oom-kill.o shmem.o
make[2]: 나감 `/usr/src/linux-2.4.16/mm' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/mm' 디렉토리

(6)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  fs
make[1]: 들어감 `/usr/src/linux-2.4.16/fs' 디렉토리
rm -f fs.o
ld -m elf-i386  -r -o fs.o open.o read-write.o devices.o file-table.o buffer.o super.o block-dev.o char-dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o attr.o bad-inode.o file.o iobuf.o dnotify.o filesystems.o namespace.o seq-file.o noquot.o binfmt-script.o binfmt-elf.o proc/proc.o partitions/partitions.o ext2/ext2.o isofs/isofs.o nls/nls.o autofs4/autofs4.o devpts/devpts.o jfs/jfs.o
make[1]: 나감 `/usr/src/linux-2.4.16/fs' 디렉토리

(7)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  net
make[1]: 들어감 `/usr/src/linux-2.4.16/net' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/net' 디렉토리

(8)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  ipc
make[1]: 들어감 `/usr/src/linux-2.4.16/ipc' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/ipc' 디렉토리
rm -f ipc.o
ld -m elf-i386  -r -o ipc.o util.o msg.o sem.o shm.o
make[2]: 나감 `/usr/src/linux-2.4.16/ipc' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/ipc' 디렉토리

(9)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  lib
make[1]: 들어감 `/usr/src/linux-2.4.16/lib' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/lib' 디렉토리
rm -f lib.a
ar  rcs lib.a errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust-spinlocks.o rbtree.o rwsem.o dec-and-lock.o
make[2]: 나감 `/usr/src/linux-2.4.16/lib' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/lib' 디렉토리

(10)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  arch/i386/kernel
make[1]: 들어감 `/usr/src/linux-2.4.16/arch/i386/kernel' 디렉토리
rm -f kernel.o
ld -m elf-i386  -r -o kernel.o process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys-i386.o pci-dma.o i386-ksyms.o i387.o bluesmoke.o dmi-scan.o pci-i386.o pci-pc.o pci-irq.o mtrr.o apm.o mpparse.o apic.o nmi.o io-apic.o acpitable.o
gcc -D--ASSEMBLY-- -D--KERNEL-- -I/usr/src/linux-2.4.16/include -traditional -c head.S -o head.o
gcc -D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4     -c -o init-task.o init-task.c
make[1]: 나감 `/usr/src/linux-2.4.16/arch/i386/kernel' 디렉토리

(11)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  arch/i386/mm
make[1]: 들어감 `/usr/src/linux-2.4.16/arch/i386/mm' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/arch/i386/mm' 디렉토리
rm -f mm.o
ld -m elf-i386  -r -o mm.o init.o fault.o ioremap.o extable.o
make[2]: 나감 `/usr/src/linux-2.4.16/arch/i386/mm' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/arch/i386/mm' 디렉토리

(12)
make CFLAGS="-D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  " -C  arch/i386/lib
make[1]: 들어감 `/usr/src/linux-2.4.16/arch/i386/lib' 디렉토리
make all-targets
make[2]: 들어감 `/usr/src/linux-2.4.16/arch/i386/lib' 디렉토리
rm -f lib.a
ar  rcs lib.a checksum.o old-checksum.o delay.o usercopy.o getuser.o memcpy.o strstr.o mmx.o
make[2]: 나감 `/usr/src/linux-2.4.16/arch/i386/lib' 디렉토리
make[1]: 나감 `/usr/src/linux-2.4.16/arch/i386/lib' 디렉토리

(13)
ld -m elf-i386 -T /usr/src/linux-2.4.16/arch/i386/vmlinux.lds -e stext arch/i386/kernel/head.o arch/i386/kernel/init-task.o init/main.o init/version.o \
	--start-group \
	arch/i386/kernel/kernel.o arch/i386/mm/mm.o kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o \
	 drivers/acpi/acpi.o drivers/char/char.o drivers/block/block.o drivers/misc/misc.o drivers/net/net.o drivers/media/media.o drivers/char/agp/agp.o drivers/char/drm/drm.o drivers/ide/idedriver.o drivers/cdrom/driver.o drivers/sound/sounddrivers.o drivers/pci/driver.o drivers/pcmcia/pcmcia.o drivers/net/pcmcia/pcmcia-net.o drivers/pnp/pnp.o drivers/video/video.o drivers/md/mddev.o \
	net/network.o \
	/usr/src/linux-2.4.16/arch/i386/lib/lib.a /usr/src/linux-2.4.16/lib/lib.a /usr/src/linux-2.4.16/arch/i386/lib/lib.a \
	--end-group \
	-o vmlinux
nm vmlinux | grep -v '\(compiled\)\|\(\.o$\)\|\( [aUw] \)\|\(\.\.ng$\)\|\(LASH[RL]DI\)' | sort > System.map

(14)
make[1]: 들어감 `/usr/src/linux-2.4.16/arch/i386/boot' 디렉토리
gcc -E -D--KERNEL-- -I/usr/src/linux-2.4.16/include -D--BIG-KERNEL-- -traditional -DSVGA-MODE=NORMAL-VGA  bootsect.S -o bbootsect.s
as -o bbootsect.o bbootsect.s
bbootsect.s: Assembler messages:
bbootsect.s:257: Warning: indirect lcall without `*'
ld -m elf-i386 -Ttext 0x0 -s --oformat binary bbootsect.o -o bbootsect

(15)
gcc -E -D--KERNEL-- -I/usr/src/linux-2.4.16/include -D--BIG-KERNEL-- -D--ASSEMBLY-- -traditional -DSVGA-MODE=NORMAL-VGA  setup.S -o bsetup.s
as -o bsetup.o bsetup.s
bsetup.s: Assembler messages:
bsetup.s:1716: Warning: indirect lcall without `*'
ld -m elf-i386 -Ttext 0x0 -s --oformat binary -e begtext -o bsetup bsetup.o

(16)
make[2]: 들어감 `/usr/src/linux-2.4.16/arch/i386/boot/compressed' 디렉토리
tmppiggy=-tmp-$$piggy; \
rm -f $tmppiggy $tmppiggy.gz $tmppiggy.lnk; \
objcopy -O binary -R .note -R .comment -S /usr/src/linux-2.4.16/vmlinux $tmppiggy; \
gzip -f -9 < $tmppiggy > $tmppiggy.gz; \
echo "SECTIONS { .data : { input-len = .; LONG(input-data-end - input-data) input-data = .; *(.data) input-data-end = .; }}" > $tmppiggy.lnk; \
ld -m elf-i386 -r -o piggy.o -b binary $tmppiggy.gz -b elf32-i386 -T $tmppiggy.lnk; \
rm -f $tmppiggy $tmppiggy.gz $tmppiggy.lnk

(17)
gcc -D--ASSEMBLY-- -D--KERNEL-- -I/usr/src/linux-2.4.16/include -traditional -c head.S

(18)
gcc -D--KERNEL-- -I/usr/src/linux-2.4.16/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -malign-functions=4  -c misc.c

(19)
ld -m elf-i386 -Ttext 0x100000 -e startup-32 -o bvmlinux head.o misc.o piggy.o
make[2]: 나감 `/usr/src/linux-2.4.16/arch/i386/boot/compressed' 디렉토리

(20)
gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o tools/build tools/build.c -I/usr/src/linux-2.4.16/include

(21)
objcopy -O binary -R .note -R .comment -S compressed/bvmlinux compressed/bvmlinux.out

(22)
tools/build -b bbootsect bsetup compressed/bvmlinux.out CURRENT > bzImage
Root device is (3, 1)
Boot sector 512 bytes.
Setup is 4768 bytes.
System is 899 kB
make[1]: 나감 `/usr/src/linux-2.4.16/arch/i386/boot' 디렉토리
			
(1)
main.o
(2)
version.o
(3)
kernel
(4)
drivers
(5)
mm
(6)
fs
(7)
net
(8)
ipc
(9)
lib
(10)
arch/i386/kernel
(11)
arch/i386/mm
(12)
arch/i386/lib
(13)
vmlinux
(14)
bbootsect
(15)
bsetup
(16)
arch/i386/boot/compressed/piggy.o
(17)
arch/i386/boot/compressed/head.o
(18)
arch/i386/boot/compressed/misc.o
(19)
arch/i386/boot/compressed/bvmlinux
(20)
build
(21)
bvmlinux.out
(22)
bzImage

위에 열거한 것과 같이 실제 컴파일에서의 순서가 명확하게 나왔다. drivers와 같은 단계에선 하위 디렉토리가 무척 많아 여러 디렉토리를 컴파일하는데 그런 것들은 모두 생략했다.