A vmlinux가 arch/arm/boot/zImage로 변환되는 과정 (그림추가)

K 2013.07.25 03:34 조회 수 : 11152 추천:1

Linux Kernel의 elf 바이너리인 vmlinux가 arch/arm/boot/zImage로 변환되는 과정을 분석해보았습니다.


우선 조성진님이 올려주신 그림부터 보겠습니다. (http://www.iamroot.org/xe/Kernel_10_ARM/173496)

Zimage.png


간략하게(?) 요약하면 다음과 같습니다.


1. vmlinux --> arch/arm/boot/Image

 : vmlinux에서 .comment 섹션과 모든 symbol 및 relocation 정보들을 제거한 후, binary 포맷(즉 그냥 데이터)으로 Image를 생성합니다.
2. arch/arm/boot/Image --> arch/arm/boot/compressed/piggy.gzip
 : Image를 gzip 압축하여 piggy.gzip을 생성합니다.
3. arch/arm/boot/compressed/piggy.gzip --> arch/arm/boot/compressed/piggy.gzip.o
 : 압축한 piggy.gzip을 데이터로 포함하고 있는 piggy.gzip.S를 컴파일하여 piggy.gzip.o를 생성합니다.

4. arch/arm/boot/compressed/piggy.gzip.o --> arch/arm/boot/compressed/vmlinux

 : piggy.gzip.o와 다른 여러 오브젝트들을 arch/arm/boot/compressed/vmlinux.lds 링커스크립트에 정의된 대로 링크하여 vmlinux elf 바이너리를 생성합니다.

5. arch/arm/boot/compressed/vmlinux --> arch/arm/boot/zImage

 : arch/arm/boot/compressed/vmlinux에서 .comment 섹션과 모든 symbol 및 relocation 정보를 제거한 후, binary 포맷(즉 그냥 데이터)으로 zImage를 생성합니다.


arch/arm/boot/compressed/vmlinux는 elf 바이너리이므로 아래의 형태로 구성됩니다.

[ELF Header]

[Program Header Table]

[Section]

  …

[Section]

[Section Header Table] 


Section Header를 확인해보면 아래와 같구요.

arch/arm/boot/compressed (master) $ arm-none-eabi-readelf -S ./vmlinux
There are 22 section headers, starting at offset 0x2beb1c:
 
 
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 001000 005a94 00  AX  0   0 32
  [ 2] .rodata           PROGBITS        00005a94 006a94 000d10 00   A  0   0  4
  [ 3] .piggydata        PROGBITS        000067a4 0077a4 29be70 00   A  0   0  1
  [ 4] .got              PROGBITS        002a2614 2a3614 00003c 00  WA  0   0  4
  [ 5] .pad              PROGBITS        002a2650 2a3650 000008 00   A  0   0  0
  [ 6] .bss              NOBITS          002a2658 2a3658 000024 00  WA  0   0  4
  [ 7] .stack            NOBITS          002a2680 2a3680 001000 00  WA  0   0  1
  [ 8] .debug_line       PROGBITS        00000000 2a4680 00263f 00      0   0  1
  [ 9] .debug_info       PROGBITS        00000000 2a6cbf 008b02 00      0   0  1
  [10] .debug_abbrev     PROGBITS        00000000 2af7c1 001697 00      0   0  1
  [11] .debug_aranges    PROGBITS        00000000 2b0e58 000188 00      0   0  8
  [12] .debug_ranges     PROGBITS        00000000 2b0fe0 0010e8 00      0   0  8
  [13] .debug_frame      PROGBITS        00000000 2b20c8 0009b8 00      0   0  4
  [14] .debug_loc        PROGBITS        00000000 2b2a80 008d36 00      0   0  1
  [15] .debug_str        PROGBITS        00000000 2bb7b6 0013f7 01  MS  0   0  1
  [16] .comment          PROGBITS        00000000 2bcbad 000010 01  MS  0   0  1
  [17] .note.gnu.gold-ve NOTE            00000000 2bcbc0 00001c 00      0   0  4
  [18] .ARM.attributes   ARM_ATTRIBUTES  00000000 2bcbdc 00002d 00      0   0  1
  [19] .symtab           SYMTAB          00000000 2bcc0c 0012d0 10     20 194  4
  [20] .strtab           STRTAB          00000000 2bdedc 000b5f 00      0   0  1
  [21] .shstrtab         STRTAB          00000000 2bea3b 0000e0 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)


위에서 설명한 5번 과정(.comment 섹션과 모든 symbol 및 relocation 정보를 제거)을 거치면 .text, .rodata, .piggydata, .got, .pad의 다섯개 섹션만 남게 됩니다. (남게 된다는 표현보다는, 결과적으로 zImage에 다섯개 섹션만 남아있었습니다.^^)


정말 그런지 한번 확인해보겠습니다.


먼저 arch/arm/boot/zImage의 시작부분과 끝부분을 확인합니다.

$ hexdump arch/arm/boot/zImage | head -n4
0000000 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1
*
0000020 02 00 00 ea 18 28 6f 01 00 00 00 00 58 26 2a 00
0000030 00 90 0f e1 19 0e 00 eb 01 70 a0 e1 02 80 a0 e1

$ hexdump arch/arm/boot/zImage | tail -n4
02a2630 a4 67 00 00 14 26 2a 00 60 09 00 00 78 26 2a 00
02a2640 74 26 2a 00 00 00 00 00 00 00 00 00 00 00 00 00
02a2650 00 00 00 00 00 00 00 00                        
02a2658


그리고 arch/arm/boot/compressed/vmlinux의 0x001000 위치(.text섹션의 시작오프셋)와 0x2a3630 위치(.pad섹션의 거의 끝오프셋)를 확인합니다.

$ hexdump -s 0x1000 arch/arm/boot/compressed/vmlinux | head -n4
0001000 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1
*
0001020 02 00 00 ea 18 28 6f 01 00 00 00 00 58 26 2a 00
0001030 00 90 0f e1 19 0e 00 eb 01 70 a0 e1 02 80 a0 e1

$ hexdump -s 0x2a3630 arch/arm/boot/compressed/vmlinux| head -n4
02a3630 a4 67 00 00 14 26 2a 00 60 09 00 00 78 26 2a 00
02a3640 74 26 2a 00 00 00 00 00 00 00 00 00 00 00 00 00
02a3650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*


일치하는군요..

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 커널 스터디 관련 Q&A 게시판 입니다. [5] woos 2016.04.09 2197
1705 리눅스 커널 동영상 강의 [9] 이혁 2011.05.01 11198
» vmlinux가 arch/arm/boot/zImage로 변환되는 과정 (그림추가) [1] file K 2013.07.25 11152
1703 (ARM )커널 분석 6차의 분석 자료를 공유합니다. [23] file 윤석훈 2011.05.27 11061
1702 커널소스 다운 받는 방법 [4] 맥주 2007.12.02 11027
1701 잡담. 우리가 스터디 하고있을때.. [4] 유상민 2007.09.02 10844
1700 do_fork(), sys_clone()... 분석-수정본 [7] 최문규 2010.04.18 10838
1699 Java에서 전처리기 사용하기. [1] 이혁 2011.05.16 10824
1698 가상주소를 물리주소로 변환에 관하여... [7] file myskan 2011.04.11 10428
1697 cache의 clean과 flush [1] 이수연 2008.01.28 10423
1696 [slab참고문서] 문경원 2008.03.22 10417
1695 0630 [6] 김강년 2007.07.01 10378
1694 다음주에 공부할 U-boot 관련자료 입니다. [추가 자료 첨부합니다 3/22] [7] file 서두원 2007.03.19 10260
1693 스터디 주제에 대한 의견을 스프링 노트에 올렸습니다. 선준규 2008.07.17 10258
1692 about 'magic number in dl' 조용락 2008.11.07 10214
1691 남표씨 짱!! [6] 김기태 2008.04.21 10198
1690 Linux for PowerPC Embedded Systems HOWTO [1] 김종화 2007.05.28 10190
1689 얼굴 못본지 거의 한달이 넘어가는군요.. [1] 서두원 2007.08.19 10187
1688 [정보] 서버 ip 모르시는 분들을 위해 알려드립니다. [1] 이정우 2008.04.29 10185
1687 PPC64 의 경우 궁금한 점 ??? [1] 장석원 2007.07.14 10170
1686 민토에서 [2] 김종화 2007.05.21 10166
XE Login