Part12. 커널(Kernel) 및 프레임워크(Framework) 설명

원문 :  http://kkamagui.springnote.com/pages/348766

 

들어가기 전에...

0.시작하면서...

 이제야 커널을 설명하게 됬다. 커널을 설명하기까지 참 많은 내용을 다룬 것 같은데, 이번에는 간단히 기능적인 소개만 할 것이므로 편하게 읽으면 된다.

 

1.FW 폴더 파일 설명

 프레임워크 소스를 열여보면 00Kernel 폴더 아래에 FW 폴더가 있다. 그 안에 세부파일들이 있는데, 이 폴더 아래의 파일들은 프레임워크를 구성하는 핵심 파일들이다.

 각 파일의 역할은 아래와 같다.

  • asm.asm : Kernel에서 사용하는 어셈블리어 코드 모음. 실제 커널이 1M위치에 로딩되었을 때 제일 먼저 실행되는 kInit 함수 포함.
  • asm.h : C 언어에서 사용할 수 있도록 어셈블리어 함수에 대한 선언
  • DefineMacro.h : 커널에서 사용하는 매크로에 대한 정의
  • DefineStruct.h : 커널에서 사용하는 구조체에 대한 정의
  • Descriptor.c/h : GDT에 대한 설정 및 인터럽터 처리를 위한 Interrupt Descriptor Table(IDT)에 대한 구현
  • GlobalValue.h : 커널에서 사용하는 글로벌 변수들에 대한 정의
  • Interrupt.c/h : 인터럽트 서비스 루틴(ISR)에 대한 구현
  • Isr.asm/h : 실제 Interrupt가 발생했을 때, 1차로 호출되는 ISR 함수 구현
  • Kernel.c : 커널 엔트리 루틴 구현. 프레임워크의 엔트리를 호출
  • Keyboard.c/h : 키보드 드라이버에 대한 구현
  • StdLib.c/h : Standard Library에 대한 구현
  • Task.c/h : 태스크 관리 및 스위칭에 대한 구현

 

2.함수 호출 순서(Call Graph)

2.1 커널 시작 시 함수 호출 순서

 커널이 실행되었을 때, 프레임워크의 엔트리 함수가 불리기까지 과정을 한번 살펴보자.

커널_실행_순서.PNG

<커널 시작시 함수 호출 순서>

 

 Asm.Asm의 kInit() 함수를 시작으로 각 함수가 위와 같은 순서로 호출된다. 맨 마지막에 프레임워크 엔트리 함수를 호출하게 되는데, 프레임워크 엔트리 파일을 수정함으로써 원하는 기능을 추가 할 수 있다.  만약 프레임워크의 기능을 바꾸고 싶으면 위에 흐름을 참조해서 원하는 부분에 기능을 추가하자.

 커널 코드 부분은 C 코드로 되어있고 주석이 어느정도 달려 있으므로 궁금한 사람은 개별적으로 분석하면 된다. 이제 슬슬 커널 프레임워크를 사용해서 커널을 제작하기 시작할텐데, 커널을 제작하면서 많이 쓸만한 함수를 모아서 참고. 프레임워크 주요 함수들에 정리해 두었으니 참고하자.

 이 정도의 함수 정도만 알아도 간단한 커널을 제작하는데 큰 문제가 없을 것이다. 실제로 이보다 훨씬 많은 함수가 있지만 Architecture에 의존적인 부분이 많아서 별로 사용할 일이 없다.

 

2.2 kInit() 함수의 비밀

 프레임워크에서 가장 먼저 실행되는 함수가 Asm.Asm 파일에있는 kInit() 함수라고 하였다. 다시말하면 1M의 주소에 위치하는 함수가 kInit() 함수라는 말인데, 수많은 함수가 커널 링크 시에 합쳐지는데 어떻게 kInit() 함수를 제일 처음으로 위치시킬 수 있을까? 비밀은 makefile에 있다.

 

2.2.1 프레임워크 1.0.3 버전 이전

 makefile을 열어보면 아래와 같은 부분을 발견할 수 있다.

  1. #Object 파일 이름 다 적기
    #아래의 순서대로 링크된다.
    OBJ = A.o K.o Is.o D.o Int.o Key.o Stdlib.o Task.o FW.o KShell.o
  2. Kkernel: $(OBJ)
    ld $(OBJ) -o kkernel.bin --oformat binary -Ttext 0x100000

 위에서 나와있듯 A.o 파일이 가장 처음에 위치시켜 Asm.Asm 파일을 가장 먼저 링크하며, Asm.Asm 파일의 가장 앞에 kInit() 함수를 위치시킴으로써 kInit() 함수를 첫 함수로 링크할 수 있다.

 

2.2.2 프레임워크 1.0.3 버전 이후

  1. ...... 생략 ......
  2. #Object 파일 이름 다 적기
    #아래의 순서대로 링크된다. 새로운 파일이 생기면 뒤에 다 추가하자
    #커널에 꼭 필요한 Object 파일들. ASM.o 파일은 항상 제일 앞에 와야한다. 그 이유는
    #커널의 엔트리포인트가 있는 함수이기 때문이다.
    ESSENTIALOBJ = Asm.o Isr.o
  3. ...... 생략 ......
  4. # 최종 링크
    kernel: $(ESSENTIALOBJ) $(CFILEOBJ)
     @echo "==> Making Kernel..."
     $(LD) $(ESSENTIALOBJ) $(CFILEOBJ) -o kkernel.bin --oformat binary -Ttext 0x100000 @echo "==> Complete"
  5. ...... 생략 ......

 

 

3.Custom 폴더 파일 설명

 00Kernel 폴더 아래에 Custom 폴더는 프레임워크를 사용해서 만든 간단한 커널 템플릿 파일(Framework.c, Framework.h)이 들어있다. 이 폴더는 프레임워크를 이용해서 기능을 추가할때 사용자가 추가한 파일들을 저장하는 폴더로 주로 작업하는 폴더가 될 것이다. 커널 템플릿 파일은 프레임워크 엔트리 함수와 외부 인터럽트 발생시 그것을 처리하는 콜백 핸들러(Callback Handler)로 구성되어있다.

 아래는 Framework.h 파일의 내부이다. 함수 이름만 봐도 함수의 역할을 추측할 수 있다.

  1. void FrameWorkEntry( void );
  2. void kIsrTimerCallBack( void );
    void kIsrKeyboardCallBack( void );
    void kIsrMouseCallBack( void );
    void kIsrCom1CallBack( void );
    void kIsrFloppyCallBack( void );
    void kIsrPrimaryHardDiskCallBack( void );
    void kIsrSecondaryHardDiskCallBack( void );

 

 그리고 아래는 Framework.c 파일의 내부이다.

  1.  /**
        Framework 구현 함수
  2.     Written KKAMAGUI, http://kkamagui.tistory.com */
  3. #include "../FW/DefineMacro.h"
    #include "KShell.h"
  4. /**
        Kernel이 시작되었을 때 다른 정리작업을 마치고 제일 처음 부르는 함수
            수정
    */
    void FrameWorkEntry( void )
    {
        // 인사말을 찍는다.
        printxy( 1, 7, "KKAMAGUI OS FrameWork Start" );
  5.     // 간단한 쉘 실행
        Shell();
    }
  6. /**
        Timer Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrTimerCallBack( void )
    {
        Scheduler();
    }
  7. /**
        Keyboard Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrKeyboardCallBack( void )
    {
  8. }
  9. /**
        Serial Com 1 Interrupt의 Callback
            필요한 경우 수정
    */
    void  kIsrCom1CallBack( void )
    {
  10. }
  11. /**
        Floppy Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrFloppyCallBack( void )
    {
  12. }
  13. /**
        Primary HardDisk Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrPrimaryHardDiskCallBack( void )
    {
  14. }
  15. /**
        Secondary HardDisk Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrSecondaryHardDiskCallBack( void )
    {
  16. }
  17. /**
        Mouse Interrupt의 Callback
            필요한 경우 수정
    */
    void kIsrMouseCallBack( void )
    {
  18. }

 프레임워크 엔트리 함수에는 간단히 환영 메시지를 출력하고 커널 쉘(kShell)을 실행하도록 되어있다. 타이머 콜백에는 스케줄러 함수가 등록 되어있는 것을 보아 스케줄러가 동작하고 있다는 것을 추측할 수 있다.

 커널에 기능을 확장하고 싶으면 위와 같이 필요한 부분에 코드를 삽입하여 원하는 기능을 구현할 수 있다.

 

 

4.마치면서...

 간단하게 커널과 프레임워크에 대해서 알아봤다. 다음에는 실제 프레임워크 파일을 수정하여 커널에 기능을 추가해보자.

 

 

5.첨부

 

 

 

이 글은 스프링노트에서 작성되었습니다.

이 글은 스프링노트에서 작성되었습니다.

+ Recent posts