리눅스 커널을 Line-by-line으로 분석하려면, 특히 리눅스 커널 이미지가 처음부터 실행되는 모습을 보고자 한다면!

몇 가지 배경 지식을 알고 있어야 한다.


이 간단한 배경 지식들을 알게 되었거나 링크를 눌러보면서 읽고 알게 되었다면 이제부터!

Linux를 Line-by-line으로 보기 위해서 리눅스의(ARM architecture의 arm64) 처음 시작점부터 알아보려고한다. 



1

2

3

4

5

6

7

8

 ENTRY(_text)


    ...

. = KIMAGE_VADDR + TEXT_OFFSET;

.head.text : {
    _text = .;
    HEAD_TEXT
}


첫 번째 줄이 바로 위에 설명한 ENTRY 지시어이다. 이는 "지금 컴파일의 결과물로 나오는 프로그램 이미지의 시작은 _text 라는 symbol이다." 라는 뜻이며 이러한 정보를 컴파일러에게 힌트로 제공해주는 것이다.

다섯 번 째 줄은 컴파일의 결과물 즉, 이 프로그램 이미지는 ".head.text" 라는 섹션을 포함하는데 이 섹션에는 이러한 내용들이 들어가 있다.
이 section에서 _text 심볼의 값을 assign해주고 있는데 그 값은 "." 즉, 위에 KIMAGE_VADDR + TEXT_OFFSET에 해당하는 값이다.
그리고 7 번째 줄에 있는 HEAD_TEXT라는 매크로 살펴보면

#define HEAD_TEXT  KEEP(*(.head.text)) 


이와 같이 정의되어있다. Linking 할 모든 Object 파일들의 "head.text" section을 모아 여기에 링킹 하겠다 하는 의미이다.

밑에서 head.S 내용에서 보겠지만 head.S의 일부 코드도 이 section에 포함되어있는 코드들이다.


그럼 이제 이러한 배경 지식을 갖고 리눅스의 처음(head.S) 으로 가보겠다.


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32

     __HEAD
_head:
    /*
     * DO NOT MODIFY. Image header expected by Linux boot-loaders.
     */
#ifdef CONFIG_EFI
    /*
     * This add instruction has no meaningful effect except that
     * its opcode forms the magic "MZ" signature required by UEFI.
     */
    add    x13, x18, #0x16
    b    stext
#else
    b    stext                // branch to kernel start, magic
    .long    0                // reserved
#endif
    le64sym    _kernel_offset_le        // Image load offset from start of RAM, little-endian
    le64sym    _kernel_size_le            // Effective size of kernel image, little-endian
    le64sym    _kernel_flags_le        // Informative flags, little-endian
    .quad    0                // reserved
    .quad    0                // reserved
    .quad    0                // reserved
    .ascii    ARM64_IMAGE_MAGIC        // Magic number
#ifdef CONFIG_EFI
    .long    pe_header - _head        // Offset to the PE header.

pe_header:
    __EFI_PE_HEADER
#else
    .long    0                // reserved
#endif



첫 번째 줄에 _HEAD라는 매크로는 아래와 같이 정의되어있고, 위에서 설명한 것 처럼 _text 실볼에 해당하는 section이다.

#define __HEAD        .section    ".head.text","ax" 


EFI를 사용하지 않고 있다고 가정하고있으므로, Image의 첫번째 명령어는 14번째 줄이 될 것이다.

부트로더가 리눅스를 실행시키면 14번 째 줄 명령어를 처음으로 실행하게 되고, 즉 stext 함수를 실행하게 된다.


다음부터는 stext 함수에 대해서 보겠다.







따로 만들어야 하는 문서: 링커스크립트, ELF, 섹션

+ Recent posts