ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OS] 12. Kernel C
    OS/OS from Scratch 2021. 6. 26. 15:41

    서론

    이번 강의에서는 C언어로 지금까지 작성했던 Low-Level 코드들을 만들겠습니다. 해당 Github 강의는 다음과 같습니다.

    https://github.com/cfenollosa/os-tutorial/tree/master/12-kernel-c

     

    cfenollosa/os-tutorial

    How to create an OS from scratch. Contribute to cfenollosa/os-tutorial development by creating an account on GitHub.

    github.com


    이론

    Linking

    이 블로그에서 Linking에 대해 알기 쉽게 설명해 놓았습니다. A.cpp라는 파일을 컴파일하면 A.o라는 Object Code가 생성되는데, 이 Object Code는 기계어로 작성된 로직과 디버깅, Symbol 정보 등의 부가적인 정보들이 있는 파일입니다. 생성된 Object Code들은 Linker에 의해 Linking 되어 실행파일이 만들어집니다. 이 과정에서 여러 Object Code들을 하나로 합치고, 여기에 라이브러리 파일들을 합쳐 실행 파일을 만들게 됩니다.


    코드

    function.c

    본 강의에서는 다음 C 코드를 이용해 실습을 진행하겠습니다.

    int my_function() {
        return 0xbaba;
    }

    Object Code

    아래 명령어는 Object 파일을 만드는 코드입니다. 

    i386-elf-gcc -ffreestanding -c function.c -o function.o

    Object 파일을 보기 위해서는 다음 명령어를 사용합니다.

    i386-elf-objdump -d function.o

    생성된 Assembly 코드는 Nasm Assembly와 문법이 달라 추후에 분석하도록 하겠습니다.

    Link

    앞서 언급했듯이 실행 파일을 만들기 위해서는 Linker가 여러 Object 파일을 하나의 Binary 파일로 만듭니다. Linking 과정에서 call <Label> 명령어들은 call 0x12345 와 같이 output 파일에서 Label이 저장되는 주소 offset으로 변환되게 됩니다. Link 하는 명령어는 다음과 같습니다.

    i386-elf-ld -o function.bin -Ttext 0x0 --oformat binary function.o

    위 명령어에서 -Ttext 0x0은 Linker에게 모든 데이터들이 저장되는 주소를 0x00에 대한 상대주소가 되게 합니다. 다시 말해, -Ttext 0x0은 이전 강의에서 본 org 명령어와 같은 역할을 해줍니다. 

    생성된 Binary 파일을 Disassemble 하는 명령어는 다음과 같습니다.

    ndisasm -b 32 function.bin

    이를 수행하면 다음 결과를 얻습니다.

    00000000  55                push ebp
    00000001  89E5              mov ebp,esp
    00000003  B8BABA0000        mov eax,0xbaba
    00000008  5D                pop ebp
    00000009  C3                ret
    이하 중략...

    위 코드를 조금 분석해보겠습니다. C언어는 지역 변수들을 Stack에 저장하는데 이를 위해 ebp 레지스터를 현재 Stack의 가장 위인 esp 레지스터의 값으로 지정해 비어있는 Stack을 생성합니다. 이 과정을 Stack Frame을 생성하는 과정이라 부르며, 이전 프로세스에서 사용 중인 ebp 레지스터의 값을 저장하기 위해 push ebp 명령어를 사용합니다.

    function.c 에서는 return 0xbaba; 코드가 있었는데 이는 mov eax, 0xbaba로 번역됩니다. 즉 함수에서 리턴되는 값은 eax 레지스터에 저장되게 됩니다. 마지막으로 ret 명령어가 실행되기 전에 ebp 레지스터를 함수가 호출되기 전 상태로 돌려놓기 위해 pop ebp 명령어가 생성됩니다.

    'OS > OS from Scratch' 카테고리의 다른 글

    [OS] 14. Checkpoint  (0) 2021.06.28
    [OS] 13. Kernel Barebones  (0) 2021.06.27
    [OS] 11. Kernel Cross Compiler  (0) 2021.06.23
    [OS] 10. 32 bit Enter  (0) 2021.06.23
    [OS] 09. GDT  (0) 2021.06.22
Designed by Tistory.