ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 임베디드 OS개발 CH3
    Share/OS 2021. 2. 20. 14:58
    이만우 선생님의 "임베디드 OS개발 프로젝트" 를 기반으로 작성하였으며, 
    학습목적으로 작성한 것이며, 자세한 내용을 모두 기술하진 않았습니다. 

     

    ch2

    설치는 책을 보고...^^ 

     

    서론 

      기본개념이 필요하다 

     - 컴파일 

     - Linker 

     - Makefile 역할 

     - 레지스터  등 

     

    목적 

     

    대목적:  OS를 만들어보자 

     

    이번챕터 #CH3의 목적 : 

     

    • Entry.S를 만들고,링커 스크립트를 작성하자
    • makefile을 만드는 방법과 qemu를 통한 gdb 를 사용했을때, 레지스터 변화를 살펴보고 깨닫자.  
    • gdb 사용방법을 익히고, 펌웨어개발 기본을 파악한다. 

     

     

     

    일단 시작 

     

    $mkdir boot
    

     

    일단 작성하는 Entry.S 

     

    .text
      .code 32
    
      .global vector_start
      .global vector_end 
    
      vector_start:
            LDR R0, R1
      vector_end:
       .space 1024, 0
    .end 
    
    
    

     

    여기서 주의하게 볼 것은

    vector_start 부분이다 

     

     

    ARM 이라는 하드웨어안에 많은 "레지스터" 가 있을 것이다.

    그 레지스터에 이름이 R0, R1, R2, 이런식으로 이름을 붙여놨다. (ARM 회사가 ) 

    ARM 레지스터에 대한 자세한 내용은 Google로 더 쌓아가기 

     

     

    Entry.S를 일단 작성은 했는데... 그래서 뭐.... what ?! 

    이 코드를 "컴파일" 해서 "바이너리 덤프"를 만들자.

     

    /boot$ arm-none-eabi-as -march=armv7-a -mcpu=cortex-a8 -o Entry.o ./Entry.S
    /boot$ arm-none-eabi-objcopy -O binary Entry.o Entry.bin
    /boot$ ls
    Entry.bin  Entry.o  Entry.S
    /boot$ hexdump Entry.bin
    0000000 0001 e1a0 0000 0000 0000 0000 0000 0000
    0000010 0000 0000 0000 0000 0000 0000 0000 0000
    *
    0000404
     
    •  arm-none-eabi-as 라는 ARM용 어셈블러 
    • 대략, 첫줄만 보고 예상할 수 있는 것은 cortex-a8 arm 코어를 사용할 것이고~ 아키텍쳐는 armv7-a를 사용하겟다~~등등 그리고 object 파일은 어떻게 뽑아라~ 라는 명령

     

    어찌되었던, 실행 파일 만들자 

     

    "QEMU가 펌웨어 파일을 읽어서 부팅하려면 입력으로 지정한 펌웨어 바이너리 파일이 ELF 파일 형식이어야 한다"

    ELF : 리눅스의 표준 실행 파일 형식.

     

    링커가 동작하려면 링커에 정보를 던져주는 파일이 필요한데, 이것이 바로 "링커 스크립트"

     

    계속해서 나오는 개념들 단어들 에 대한 의미를 구글링하고 찾아가면서 책을보는 것을 추천한다. 

    그래야 booting 되는 과정에서 코드들이 컴파일되고 링킹되는 과정과 메모리가 바뀌는 부분들을 더 깊게 이해할 수 있다. 

     

     

    navilos.ld

    ENTRY(vector_start)
    SECTIONS
    {
     . = 0x0;
    
     .text :
     {
      *(vector_start)
      *(.text .rodata)
     }
    
     .data :
     {
      *(.data)
     }
    
     .bss :
     {
      *(.bss)
     }
    }
    



     

    QEMU 사용 

     

    QEMU는 하드웨어 가상머신/Emulator 이라고 생각한다. 

    보통 우분투나 다른 OS를 윈도우에서 VM를 쓰듯이... 

     

     

    개발할때 구조는 쉽게 표현하면 이렇다. 

    한 터미널에서 qemu를 생성하여 서버를 열고 

    다른 한 터미널에서 gdb를 이용해서 그 서버에 접속하는 방식이다 

     

     

    처음시작할때는 이 구조가 어떤지 조차 몰라서, 터미널을 어떻게 켜야되고 어떻게 어디서 명령을 실행해야되는 것 조차 헷갈릴 수 있다. 

    QEMU를 통해서 지금까지 작성햇던 boot , linking에 필요한 코드들을 실행한다, 

     

    $ qemu-system-arm -M realview-pb-a8 -kernel navilos.axf -S -gdb tcp::1234,ipv4
    VNC server running on 127.0.0.1:5900
    

     

    혹시나 같은 주소로 열었다면, 안열리니 주의 ! 

     

    저 상태는 qemu를 통해서 실행이 되었고 서버를 열어놨다는 뜻이니, 

     

    터미널2, 하나 더 만들어서 저기에 연결을 시도하자. 

     

    (gdb말고도 다른 것들이많은데 일단 책 따라 이것을 쓰자)

     

    *책에서는 

    arm-none-eabi-gdb를 사용했으나, 

    환경문제로인해(우분투 18.04 및 VM 사용) 

     

    gdb-multiarch 

     

    를 사용했다. 이부분에서 에러가 많이 나는 것을 보았다. 아래 참조의 글들을 참고하면 좋을듯하다 

     

    qemu <----> gdb 연결 

     

    지금까지 정리해보자 

     

    지금까지의 과정을 생성부터 실행이라고 본다. 

     

    1.파일을 생성하고,

    2. 그것을 실행하기 위해서는 컴파일 하고 가상머신안에서 돌려야 되고 빌드 등등의 일련의 작업이 했다. 

     

    Makefile을 통해 빌드를 자동화 하자 

     

    *자세한 설명은 책 참고 

     

    참고로 작성시 Tab으로 초기 칸을 띄어야 한다는 것 ! 

     

     

    Makefile

     

     

    makefile 작성도 책 참조...

     

    *뜬금없는 이야기지만, 

    명령어를 써서 하는 이런 느낌?이 웹개발시 nodejs npm환경설정하는 것도 그렇고, front와 연동할때 많이 쓰이는 웹팩같은 환경설정과 유사하네..

     

    무튼 

    makefile을 만든 이후에는 

     

     

    #terminal1 

    make

    make debug

     

     

    #terminal2

    make gdb

     

    #물리자~

    (gdb) target remote:1234

    (gdb) file build/navilos.axf

     

     

    디버깅을 시작할 수 있다. 

     

     

     

     

    느낀점 

     

    1. 하드웨어 기본개념/ 용어에 대한 깊은 이해의 필요성 

     

    CH3의 내용을 한줄 요약하자면 , 

    작성 - 컴파일 -링킹 - 빌드 - 설치 - 실행 

    인데, 이과정속에서 컴파일러를 다운받고, 

    컴파일러를 통해서 오브젝트 파일을 링커에 물리고 

    실행 하는 과정 

     

    Makefile 을 이용해서 더욱 간편하게 자동화 빌드환경을 구축하는 것을 한것이다. 

     

    한줄이 좀 길었지만, 이렇다고 본다. 

    여기서 중요한것은, 한줄한줄을 따라하는 것도 중요하고, 

    그 각개념이 어떻게 무엇을 하는것인지 대강 감을 잡아야 할것같다. 

     

    왜냐면 이것이 GUI기반으로 추후 개발을 하는 과정에 있어서도, 

    porting을 한다거나 하는 경우에 어느 과정에서 어떻게 적용시켜야될지를 알아야 하기때문이다

     

     

     

     

    2. 커널 디버깅이란 무엇인가 

     

    난 커널 디버깅이라는게, 커널은 계속 "스스로" 돌아가는 와중에 

    내가 잡은 breakpoint에서 멈추고 결과를 보는 것으로 생각했는데, 

    이번과정을 통해서 생각이 조금 바뀌었다. 

    커널을 스스로 돌아가는 어떠한 프로그램이 아니라,

    내가 "구동"을 시키면서 메모리변화 (추후에는 여러 I/O가 되겠지?) 를 보는 것이구나.

     

    를 깨닫게 되었음. 

     

     

    3. 개발 매커니즘이 참 비슷함. 

     

    웹이든, 임베디드든, 

    쉽게 작성하고 직관적으로 실행하려는 욕심?이 참 유사하다는 것이 신기했다. 

     


    참고자료 

     

     

     

    kldp.org/node/162560

     

    펌웨어 RTOS 책을 썼습니다. | KLDP

    10년만에 책을 한 권 썼습니다. 10년전에 KLDP에 쓴 글을 바탕으로 책을 냈었습니다. 이 책이죠. 아직도 절판되지 않고 팔리고 있습니다. 10년동안 꾸준히 일정 권수만큼 매년 팔리는 것 보면 아마

    kldp.org

     

    댓글

실험중인 삶, Life is not a race