[OS 개발 7] 32비트 커널 로더(1) - 커널과 디스크 구조


1. 커널 로딩


드디어 OS의 핵심이라고 볼 수 있는 커널을 로딩하는 단계까지 왔습니다. 부트로더 포스팅만 해도 시간이 꽤 걸렸는데, 앞으로 커널 로더를 구현하는 부분은 얼마나 걸릴지 모르겠네요.

 

이전 포스트까지 디스크의 MBR 영역에서 부트 로더 프로그램을 읽어들이는 코드를 만들어 보았습니다. 그런데 512 바이트 영역은 내가 진짜 만들고자 하는 OS 프로그램을 넣어서 실행하기에는 굉장히 작은 공간이죠. 따라서 디스크 MBR 영역 다음의 영역에서 OS 커널 프로그램을 읽어들이고 이를 메모리 공간에 적재하는 과정이 필요합니다. 부트 스트랩 과정에서 5단계에 해당할 것입니다. 아래 링크를 통해 다시 한번 그 절차를 살펴보도록 하겠습니다.

 

2016/02/03 - [분석연구소/운영체제 구조] - [OS 만들기 4] 준비 단계(3) - 부트스트랩 과정

 

 

그리고 '부트로더에서 커널을 로딩' 하는 방식에 대해서 개념화 해 본다면 다음과 같습니다.

 

 

32비트 커널(Kernel) 로딩. 디스크에서 MBR을 통해 메모리 적재MBR 영역에서 커널 탐색 및 메모리 적재

 

 


2. 디스크 구조


 

이제 위와 같은 구조를 구현하기 위해 부트 로더 프로그램 내부에서 커널로 점프하고, 커널 영역에서 작업할 프로그램을 별도로 작성하면 됩니다.

 

그런데, 커널 영역을 구현하기에 앞서, 디스크 구조에 대해서도 어느 정도 알고 있어야 합니다. 왜냐하면 디스크의 어느 부분에서 어떻게 커널 프로그램을 인식하고, 이를 램에 넘길 것인가를 CPU에 알려야 하기 때문입니다. 사실 디스크 구조도 깊이 파고들면 내용이 광범위해져서 자칫 본 포스팅의 범위를 넘어설 수 있습니다. 따라서 간략하게만 짚고 넘어가기로 하겠습니다. 혹시 디스크에 대해 구체적인 분석이 필요하게 되면 나중에 별도의 포스팅으로 다루도록 하겠습니다.

 

우선 디스크의 구조를 살펴보면 다음과 같습니다.

 

 

 

 

디스크의 첫 번째 섹터가 MBR 영역이 될 것이며, 이 MBR 영역에 지난번 내가 만들었던 boot1.img 파일이 저장되어 있을 것입니다. 따라서 우리는 다음 섹터에 커널 프로그램을 저장하고 이를 메모리에 적재하는 부분을 제작해야 합니다. 이 때 우리가 부트 코드를 통해 커널 프로그램이 디스크의 몇 번 실린더의 트랙, 섹터에 저장되어 있는지 그 위치를 지정해줘야 합니다.


 

이를 위해 실린더나 헤더, 섹터 번호 등을 가리키는 특정 레지스터에 커널을 읽어들이고자 하는 디스크 구역의 번호를 지정하면 됩니다. 다음 코드와 같은 방식으로 말입니다. 구체적인 설명은 아래의 주석을 참고하면 됩니다. 단, 여기에서 주의할 점은, 모든 번호는 0부터 시작한다는 사실입니다. 즉, MBR 영역은 이미 0번 실린더의 0번 헤드, 0번 섹터에 존재하므로, 커널 영역은 0번 실린더의 0번헤드, 1번 섹터에 저장될 것입니다. (참고로 cl과 같이 '어디서부터 어디까지 읽을 것이다 와 같은 개수를 의미할 때는 처음 1부터 시작합니다)

 

32비트 커널(Kernel) 로딩 디스크 셋팅 코드커널 영역 참조를 위한 디스크 셋팅 코드

 

위 코드는 처음 디스크를 읽고 적재하고자 하는 메모리의 적재주소를 지정하게 됩니다. 세그먼트:오프셋 방식이 아직 낯설다면, 아래 링크를 통해 이전 포스팅에서 상대주소 지정 방식에 대해 다시 한번 복습해보도록 하겠습니다.

 

2016/02/03 - [분석연구소/운영체제 제작] - [OS 만들기 6] 레지스터 세그먼트와 오프셋 (segment:offset) 개념

 

다음으로 ah, dl, ch, dh, cl, al과 같은 레지스터를 사용하여 우리가 원하는 디스크 영역의 번호를 지정해 줍니다. 각각 의미하는 바는 주석을 참고하면 되겠습니다. 그리고 마지막으로 인터럽트(int, Interrupt) 13h을 사용하여 우리가 디스크를 이제 읽어들이겠다는 신호를 CPU에 전달하면 됩니다. 인터럽트 개념은 뒤에서 구체적으로 다뤄보도록 하고, 일단 이번 포스팅에서는 이정도로만 확인하면 될 것 같습니다.

 

위의 코드에는 최소한의 디스크 영역만 설정해 놓았지만, 이 밖에도 굉장히 많은 설정 방법이 있습니다. 이를 따로 지정하고자 한다면, 아래 사이트에서 인터럽트 0x13에 대한 옵션들을 참고하시기 바랍니다. 양이 방대하므로 링크를 걸어두도록 하겠습니다.

 

INT 13H 옵션: https://en.wikipedia.org/wiki/INT_13H

 


3. 다음 진행할 작업


지금까지 부트로더에서 읽고자 하는 디스크를 설정하는 코드까지 작성해 보았습니다.

 

이제 커널 프로그램이 저장된 영역으로 점프하는 부분과 커널 프로그램 작성을 하면 됩니다.

 

그런데 저는 커널 프로그램을 작성하기 전에 운영모드 변환에 대해 우선 짚고 넘어가기로 했습니다. 다음 포스팅에서 할 예정인데, 지금 여기까지는 아직 데이터를 16비트로 처리하는 단계라서, 커널로 넘어갈 때는 32비트로 변환하는 작업이 다뤄져야 합니다. 이에 대한 내용은 다음 포스팅에서 다루도록 하겠습니다. 전체적으로 구현된 모습은 이번 32비트 커널 로더 챕터의 마지막 단계에서 공개하도록 하겠습니다.

 



TAGS.

Comments