'2009/12'에 해당되는 글 3건

  1. 2009/12/28 귀차니스트 어후.. 드디어 인터럽트 활성화가 되었군요..
  2. 2009/12/16 귀차니스트 Kernel Image에 어이없는 삽질을...
  3. 2009/12/15 귀차니스트 이제 거미줄을 정리할 때가 된 듯 합니다..

  마지막 C++ 커널 진입 글을 올리고 난뒤 많은 시간이 흐른것 같습니다. 엄청 -ㅅ- 도중에 해결할 수 없는 삽질이 계속되어 한 동안 지지부진 하고 있었는데요.. 결과는 오늘 해결을 봤습니다. 결과물은 아래와 같이 Keyboard Interrupt 처리가 되는 화면입니다.(하지만 제대로된 키 입력은 아직 처리를 못했다는게.. 가장 큰 문제라면 문제일까요?)



  위 화면에서 볼 수 있다 시피 깨진 문자가 입력이 되긴 합니다. Scan Code 를 곧바로 출력하게 하였더니 이런 현상이 발생하네요^^; 곧 piKeyboard 클래스를 제작하여 제대로 된 입력을 처리하려고 합니다. ㅎㅎ 그래도 예전에 진입만 되었던 화면이랑 많이 달라진 듯 하죠? 대충 그 동안 추가된 기능이 아래와 같습니다.

1. Memory Size Detection
  - Page Map Level 4 Table등의 메모리 테이블을 구성하여 제대로 메모리 접근이
되는지 검사하여 사이즈를 측정을 하게 하였고

2. Global Descriptor Table
 - KernelLoader 에서 임시로 롱모드 진입을 위한 GDT 데이터를 1MB 영역에 존재하는 커널에서 다시 재구성하여 로딩을 합니다.

3. Task State Segment
 - Task Segment 를 구성했구요. 이를 위해서. 뒤에 적을 하나의 구현이 필요했습니다.

4. Interrupt Descriptor Table
 - CPU에 대한 Interrupt 를 처리하기 위한 IDT를 커널영역에서 구성하였습니다. 물론 Master PIC, Slave PIC 또한 IRQ를 리맵핑하여 처리할 수 있도록 하였습니다.

6. new operator 제공
 - 아주 단순한 new 이긴 합니다만, 현재 커널 상에서 커널을 실제 운용하기 위하여 사용되는 Memory Allocation Alogorithm을 사용한 것이 아닌 문법상으로 new 를 지원합니다. 이 부분이 되어야 x64 Task State Segment 에서 사용할 스택공간을 손쉽게 마련할 수 있겠더라구요^^.

7. Global / Static Class의 Constructor, Destructor 호출
 - 기존엔 Pointer 를 Global 하게 관리하고 Stack 에 커널 오브젝트를 생성한 후, 사용을 하였는데 그 부분을 LD 와 extern "C" 를 이용하여 서로 연결 Constructor, Destructor를 KernelMain 진입 전후에 호출이 되도록 하였습니다. 이 덕분에 커널영역에 데이터가 존재하게 되었구요

  뭐 별 기능이 없는 것 같기는 합니다만. 소스 측면에서는 엄청난 변화가 있었습니다. ㅜㅜ Descriptor Table 들을 어떻게 구성할까 구성할까 하다가 Class 와 Inheritance, Union 을 사용하여 데이터에 대하여 공통적으로 접근하기 쉽도록 일단은 구성을 했었고, 최대한 namespace 를 사용하여 소스코드량은 많아질지라도 구분을 하도록 했고, Get, Set 을 통하여 OOP를 그래도 지켜보려고 했습니다. 그래도 RTTI가 안되다보니 Inheritance의 Virtual Function 같은건 사용할 수도 없습니다. 뭐.. Virtual Function 을 사용하려고 해도 Function Table 로 인하여 Class의 크기가 커지는 문제점이 있어서 손쉽게 할 수 있는 것만도 아니지만요^^;

  지금도 열나게 코딩중이긴 하지만 언제까지 달릴 수 있을지 잘 모르겠습니다^^. 그럼 다음에는 더 좋은 결과물을 들고 포스팅을 해보도록 하겠습니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/12/28 04:09 2009/12/28 04:09

댓글을 달아 주세요

  일단 제가 작업하고 있는 환경은 Ubuntu 9.10 x64 입니다. 사실 Kubuntu를 개인적으로 더 좋아하긴 하지만 사정상 사용할 수 밖에 없었습니다. 그래서 좀 덜 익숙한 환경에서 삽질을 하고 있었답니다. 무참히 컴파일과 코딩, 에뮬레이션을 번갈아가며 말이죠..

  이 OS개발이라는 작업이 제가 보기에도 모 횽님께서 하셨던 말씀인 "무한삽질"이라는 단어보다 더 잘표현할 단어는 없는 듯 보입니다. 그래서 오늘도 여러건 해먹었구요. 아우 그냥 Vmware가 픽픽 죽어나자빠지는데 어떻게 표현할 길이 없더군요. 이건 어디서 왜 죽는지도 모르는 상황이라. 그냥 답답하게 이러니 저러니 테스트하면서 개발하고 있었습니다.

KernelTest (Language : cpp)
  1. void piKernelEntry()
  2. {
  3.     CpiTextBuffer piTextBuffer;
  4.     piTextBuffer.SetPos(79, 24);
  5.     piTextBuffer.DrawCharacter('x')
  6.     piTextBuffer.DrawCharacter('x')
  7.     while(1)    ;
  8. }

  위 코드로 Video Buffer에 해당하는 메모리 구역에 문자를 직접 써넣어 주는 상황을 제작했는데, 입력위치가 오른쪽 하단 에 입력하는 것입니다. 그런데 이게 Scroll 기능을 구현하고 테스트를 하는데 마지막 줄이 스크롤 되면 무조건 Vmware 가 이유없이 리붓이 되네요 ㅜㅜ. 그렇게 해서 한 두어시간 삽질을 진행하고 한 줄씩 디버깅을 하는데!! CpiTextBuffer 라는 클래스 내부에서 'x', 'y', 'z' 에 해당하는 문자를 고정된 위치에 한 번씩 뿌리는데 y 라는 얘가 z로 변하는 게 아닙니까? @0@ 그래서.. 이걸 단서로 찾다가 찾다가 보니. 바로 ImageWriter에서 Binary모드로 파일을 오픈한게 아니더라구요 ㅜㅜ 이런.. 제길.. 이라는 말이 절로 나오더군요.
  사실은 맨 처음에 문자를 출력했는데도 불구하고 이상한 문자만 나오길래 이거 Vmware의 -ㅅ- 버그가 아닌가 내심생각을 해서 qemu 를 비롯해서 여러가지 에뮬레이터를 다운받아서 진행을 해봤고, Hex Editor 를 통한 직접적인 Kernel Image Writing을 하다보니 문제가 없었습니다. 그래서 설마 하고 Hex Editor 를 통해서 Vmware 데이터에도 써주니 제대로 동작을 하는!! @0@.. 결국 문제는 편의를 위해서 만들었던 OS Image Writer였습니다.ㅜㅜ 그래도 해결이 되어서 다행이네요.
  현재 보이는 CpiTextBuffer 라는 클래스는 TextMode VideoBuffer를 제어하기 위해서 대충 구현이 된 클래스입니다. 대략적으로 기능은 아래와 같은 함수들로 구성이 되어있네요.

void Clear();
 void Clear(unsigned char Clr);
 void Scroll();
 void Scroll(short Pos);
 void SetPos(short X, short Y);
 void GetPos(short &X, short &Y);
 void SetPosX(short X);
 void SetPosY(short Y);
 short GetPosX();
 short GetPosY();
 unsigned char GetColor();
 void SetColor(unsigned char Clr);
 unsigned char GetColor(short X, short Y);
 void SetColor(short X, short Y, unsigned char Clr);
 void DrawCharacter(char szChar);
 void DrawCharacter(char szChar, unsigned char Clr);
 void DrawText(const char *szText);
 void DrawText(const char *szText, unsigned char Clr);
 void SetDefaultColor(unsigned char Clr);
 unsigned char GetDefaultColor();

  적당할런지 모르겠습니다. 그래도 기능 구현하고 버그 찾느라 시간이 오만상 빠르게 지나가더군요 ㅜㅜ 시간을 엄청 잡아먹습니다. 에구구 ㅜㅜ 아래는 제어된 클래스에서 출력한 글자와 제 작업 환경입니다.




  일단 앞으로는 하나를 해도 엄청 주의를 해야 겠습니다. 많이 해본 것은 아니지만 이거는 약간 삐끗하면 이유없이 리부팅이 되고 그래서.. 세심한 주의를 기울여야 하는 것 같네요 ㅜㅜ
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/12/16 19:48 2009/12/16 19:48

댓글을 달아 주세요

  동방환상마작 포스팅 이후로 오랜 시간이 흐른 뒤의 포스팅입니다. 그 동안 병역특례의 기간도 끝을 보게 되었고, 한 달 여 정도 문서와 구글속에서 파묻혀 살았습니다. 사실 게임도 아주 약간 했다는 것을 숨길 수는 없겠습니다. 전체적으로 구상도가 정리되지 않는 문서를 보고 있으려니 아주 막막하더라구요^^. 그리하여 한 달 정도 여러가지 문서를 보고 다른 할 일도 처리하면서 시간을 보냈습니다. 아래의 것이 그 결과물 입니다(?)



piKernel.c (Language : c)
  1. void piKernelEntry()
  2. {
  3.     volatile char *VideoBuffer = (char *)0x0000000000b8000;
  4.     while(1)    {
  5.         *VideoBuffer = *VideoBuffer +1;
  6.     }
  7. }

  처음에 보이는 깨지는 문자를 C 로 쓴 커널Entry 에서 보이도록 만들었는데 작동합니다. ㅜㅜ 사실 여태까지 한 번도 롱모드 쪽으로는 전환해본적이 없는데 일단은 성공을 했습니다. 그런데 아마.. 이제부터 시작일 것 같군요^^; IDT를 비롯해서 Memory Management 쪽도 만들어야 하고.. 할 일이 많을것 같습니다. 맨 처음에는 BIOS 인터럽트를 이용하여 부트로더에서 커널로더를 올렸고, 커널로더에서는 x64의 롱모드로 진입 후, CHS모드를 이용하여 데이터를 직접 1MB 영역에 올렸습니다. 그런 다음에 바로 점프를 한셈이구요.
  rep 를 붙여서 명령어를 돌리는데, 왜 계속 리부팅 되지 되지 하다가.. rcx 가 아니라 ecx 로 데이터를 준 것을 발견하고 삽질 중에 고쳐서 겨우 진입 했습니다. 이게 바로 삽질의 매력(?) 인가요 ㅜㅜ 일단 어쨌든.. 앞으로 할 것이 많이 남은 듯 하군요^^;



크리에이티브 커먼즈 라이센스
Creative Commons License
2009/12/15 15:52 2009/12/15 15:52
TAG , ,

댓글을 달아 주세요