OS 만들기 -7- (Hardware Interrupt)

Operating Systems/OS 만들기 프로젝트 2010. 10. 26. 11:46 Posted by 알 수 없는 사용자

 
PC의 Hardware Interrupt는 8259A 라는 칩을 통하여 입력을 받는데 보통 PIC(Programmable Interrupt Controller)라고도 한다.



이 PIC를 제어하기 위해 PIC용 PORT 명령어 셋인 
ICW(Initialization Command Word, 8bit) ICW1, ICW2, ICW3, ICW4 

그리고 OCW(Operation Control Word) OCW1, OCW2, OCW3 에 대해서 알고 있어야 한다.






Master

Master PIC는 Interrupt가 발생하면 INT핀에 신호를 실어 CPU에 보낸다.

CPU는 신호를 받고 EFLAG Register IE비트를 1로 셋하고 Interrupt를 받을 수 있다면 /INTA를 통해 Master PIC에 보낸다.

Master PIC는 /INTA로 신호를 받으면 IRQ의 숫자를 DATA Bus를 통하여 CPU로 전달한다.

CPU는 Protected Mode라면 IDT에서 맞는 Descriptor를 찾아 Handler를 실행한다.

Slave

Slave PIC는 자신의 INT핀에 신호를 실어 Master PIC의 IRQ 2번 핀에 신호를 보낸다.

Master PIC는 INT핀에 신호를 CPU로 보낸다.

Slave PIC /INTA핀에 신호를 받으면 DATA Bus에 숫자(8~15)를 실어 CPU에 보낸다.




 각 IRQ핀은 여러가지 장치들과 위 표와 같이 연결이 되어 있다.
 


 위 두 개의 PIC가 제대로 동작하려면 초기화 과정을 거쳐야 한다. 
 ICW1 -> ICW2 -> ICW3 -> ICW4 순서대로 초기화 과정을 거치면 된다.


 이 PIC는 I/O 명령어인 out를 사용하며 Master PIC는 0x20, 0x21 Slave PIC는 0xA0, 0xA1 포트번호를 이용한다.



 ICW1 - PIC를 초기화


 4~7bit 는 정해져 있는데 보통 0으로 사용한다. LTIM은 Interrupt가 발생하였을때 엣지트리거(0), 레벨트리거(1)를 결정한다.

 SNGL은 PIC가 Master/Slave(1)로 되어있는지 Master(0)만 사용할 것인지 결정해준다.

 IC4는 ICW4 명령어가 추가적으로 필요하면 1로 필요하지 않으면 0으로 결정해준다.
 

 ICW2 - IRQ 리맵핑. CPU에 설정된 것과 구현하는 것의 충돌이 일어나기에 번호를 바꿔주는 것.

 0~2bit는 0으로 결정되어있다. 이것은 8단위로 기재해야 한다는 뜻이다.

 나머지 bit를 이용하여 Interrupt가 발생했을떄 CPU에게 숫자를 더하여 알려준다.

 예를 들어 00010000(0x10)을 넣으면 0번이 발생하였을때 CPU에게는 0x10의 숫자를 보낸다. 만약, 00100000(0x20)이라고 한다면 0번이 발생하였을때 CPU에게 0x20의 숫자를 보내어 Interrupt 번호를 결정해 준다.

 

 ICW3 - Master /Slave 연결 방법

 Master PIC. 각 비트에 0을 넣으면 하드웨어 장치에 연결이 되어 있다는 것을 나타내고 1을 넣으면 Slave PIC에 연결이 되어 있다는 것을 나타낸다.

 Slave PIC. Slave에서는 Master PIC의 몇번째 핀에 연결되어 있는지를 나타낸다. 3~7bit는 0으로 설정이 되고 나머지 bit를 이용하여 결정한다.

 예를 들면 000000102(210)이라고 설정을 해 주면 Master PIC의 2번 IRQ에 연결이 되어 있는 것이다.

 

 ICW4 - 추가 명령어.


 SFNM, BUF, M/S 기능은 현재는 구현하지 않아도 되므로 0으로 설정해준다.

 AEOIbit는 PIC를 자동으로 Reset 해줄 것인지 나타낸다. Interrupt가 발생했을 때 CPU에게 알린 후 Reset을 하지 않으면 다른 Interrupt를 받아 들이지 못한다. 

 mPMbit는 0을 넣으면 MCS-80/50 Mode로 움직이고 1을 넣으면 8086 Mode로 움직이는 것을 나타낸다.

 

port 0x20, 0xA0을 같이 사용하는 ICW1, OCW2, OCW3은 각 bit로 구별이 가능하다.

ICW1은 4bit가 반드시 1로 설정을 해야하고 OCW2는 3bit가 0 4bit가 1로 OCW3은 3bit가 1 4bit가 0으로 반드시 설정이 되기에 구별이 가능하다.

 

OCW2
 

OCW3
 
 

 

 이제 실제로 Code를 작성해 보자.




 위는 MBR Code 에서 PIC 초기화 부분이다.

 

 Interrupt Mask는 Slave PIC에서는 모든 IRQ를 막아 놓고 Master PIC에서는 2번 IRQ를 뺸 나머지를 막아 놓는다.

 Protected Mode를 넘어가면서 외적인 다른 Hardware interrupt가 걸리지 않도록 Mask 상태로 만드는 것이다.







Kernel Code 중 IDT Segment로 Descriptor를 복사하는 과정이다. 

앞서 ICW2로 ReMapping을 하였기 때문에 IRQ 0번에서 IRQ 0x20(16진수 32)로 바뀌었다.
 


Timer, Keyboard interrupt 를 위해 Mask를 해제하고 유효하게 만드는 것이다.


 



위는 각 Descriptor Pointer 부분이다.




 
Keyboard 루틴에서

in al, 0x60

명령은 Keyboard buffer에서 스캔코드를 가지고 온다. 만약 가져오지 않으면 다음 Interrupt가 발생하지 않는다.




그 이후

mov al, 0x20

out 0x20, al

명령은 PIC를 Reset 하는 명령어이다. ICW4 AEOI 비트에서 수동으로 설정을 하였기에 매번 Reset을 해주어야 한다.







 
 결과 화면이다. "This" 앞부분이 Timer Interrupt가 걸리기 때문에 매번 바뀌고 있고, Keyboard가 눌렸다 땔때마다 두 개의 문자가 바뀌는 것을 알 수 있다.

bochsrc에서 clock을 Slow로 지정해 주지 않으면 너무 빠르게 Timer Interrupt가 걸린다. 
 


 
 위 그림은 예외까지 추가하여 작성된 결과화면이다. Protected Mode에서는 Exception, Hardware Interrupt, Software Interrupt 모두 같은 IDT를 이용하기에 ICW2를 이용하여 Remapping을 해주는 것이다. 0~19번까지는 예외 처리를 위하여 할당되어 있고, 20~31까지는 Inter에서 예약해둔 Interrupt가 할당되어 있다. 32~255번까지 프로그래머가 지정할 수 있는 영역이기에 0x20을 이용하여 Remapping을 해 주었던 것이다. 

 위 결과는 Zero_devide가 예외가 발생하였을 때 나오는 화면이다. Zero_devide ISR을 보면 jmp $을 이용하여 무한루프에 빠지게 만들었기에 위 결과처럼 다른 인터럽트가 걸리지 않게 된다. 

 

예외 Kernel Code는 이제까지 한 내용으로 충분히 이해가 되리라 믿기에 따로 설명은 하지 않았습니다.

 
 

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

OS 만들기 -6- (IDT)  (0) 2010.09.14
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