OS 만들기 -6- (IDT)

Operating Systems/OS 만들기 프로젝트 2010. 9. 14. 05:32 Posted by 알 수 없는 사용자




Protected Mode에서의 Interrupt 동작은 Real Mode와는 다르다.

Real Mode에서는 Vios Interrupt를 이용하지만 Protected Mode에서는 IDT(Interrupt Descriptor Table)를 이용한다.

IDT는 256개로 GDT Descriptor와 비슷한 구조로 되어있다.

 


Interrupt Handler Offset - 인터럽트가 요청 되었을 때 그 인터럽트가 실행될 Routine의 Offset.
Interrupt Handler Segment -  인터럽트가 실행될 Routine Code가 존재하는 Segment

Type(기타 설정) - DPL, P, D bit

 


Real Mode일때 사용했던 SP(Stack Pointer)를 새로운 곳으로 지정해준다.

IDTSelector를 이용하여 IDT가 저장될 Segment를 지정해 준 후 256개의 Interrupt Descriptor를 만든다.
 
loop_idt: 라벨이 Descriptor를 만드는 부분이다.

현재 256개의 모든 Descriptor가 다 같다.

rep movsb

를 이용하여 8바이트 만큼 DS:ESI->ES:EDI 방향으로 복사하고 있다.

 

lidt를 이용해 IDTR(Interrupt Descriptor Table Register: 16bit Limit, 32bit Base Address)를 설정해 준다.

Limit = 0x7FF(2047), Base Address = 0x20000

 

Before
 
 
After
 

 

IDT와 ISR을 만든다.

 

 
먼저 GDT에 IDT의 Descriptor를 저장할 Segment를 새로 만든다.

dd 0x0000FFFF, 0x00CF9202 (Little Endian)

Base Address를 0x20000으로 지정해 주고 있다.

 

IDTR에서 사용할 Limit, Base Address를 지정해 준다.

idt_ignore: 라벨부분이 실제 IDT에 들어갈 Descriptor이다.

ist_ignore: 부분은 실제 Interrupt가 발생되었을 때 실행되어야 하는 Routine(ISR-Interrupt Service Routine)이다.

모든 Register와 Flag값을 스택에 Push후 메시지를 출력하고 끝날 때 Pop하여 본래 있던 값으로 돌려 놓는다.

 

 


위 그림에서 0x20000에 찾아가 보면 0x00080109, 0x00008E00로 ID(Interrupt Descriptor) 값이 저장되어 있다.

Offset = 0x00000109(idt_ignore Offset)

Handler Segment = 0x0008(SysCodeSelector)

P = 1(Ram에 존재), DPL = 0(privilege Level), D = 1(32bit Code Segment)

 


실제로 0x10109에 가서 확인해보면  isr_ignore Code와 같은 것으로 보아 이 곳이 ISR임을 알 수 있다.

 

Hex

Disassembler

 실제 Hex값에서도 2번째 Sector의 0x109로 가보면 ISR이라는 것을 확인 할 수 있다.

 

 

IDT와 ISR을 다 만들었다면 실험을 위해

int 0x77

을 이용하여 119번째 Interrupt를 발생시키면 ISR로 진입하는 것을 확인 할 수 있다.

 

 
 

int 0x77

와 같은 Interrupt가 걸렸을때 동작하는 과정이다.

1. CPU는 IDTR 참조

2. IDTR의 Base Address(0x20000)로 IDT의 시작 위치에 접근

3. 119 Index의 IDT에 접근

4. Handler Code Segment(SysCodeSelector) Bass Address(0x10000)

5. GDT Basee Address + IDT Offset에 접근

6. ISR 실행

7. iret 명령으로 Interrupt가 걸렸던 명령문 바로 다음명령으로 이동 

 

 

Result


  실제로 돌려보면 잘 된다는 것을 확인 할 수 있다. 만약 bochs로 실행을 했는데 자꾸 재부팅이 되는 현상이 일어난다면 그것은 IDT와 GDT 그리고 ISR이 제대로 설정이 되지 않아서 일어나는 것이다. Segment영역을 잘 맞추어 주어야만 Interrupt가 제대로 실행이 된다.

 

'Operating Systems > OS 만들기 프로젝트' 카테고리의 다른 글

OS 만들기 -7- (Hardware Interrupt)  (0) 2010.10.26
OS 만들기 -5- (GDT)  (0) 2010.09.08
OS 만들기 -4- (Protected Mode)  (3) 2010.09.08
OS 만들기 -3- (Kernel)  (0) 2010.09.08
OS 만들기 -2- (MBR)  (2) 2010.09.02
AND