Search

'CLKH64 OS/08장'에 해당되는 글 1건

  1. 2013.01.03 A20 Gate 및 I/O Ports

A20 Gate 및 I/O Ports

CLKH64 OS/08장 2013. 1. 3. 19:27 Posted by 알 수 없는 사용자

1. 마주친 어려움

A20 Gate의 내용과 I/O port의 존재..

이걸 알아야 하는 이유는.. 1MB 이상의 홀수 MB 영역에 접근하기 위해서는 A20Gate를 on시켜야 하기 때문임..

이전에 싸질렀던 글 펌 (사실 책이 더 이해가 쉬움.. 책을 보자.)

2. A20 Gate 및 HMA


 


0h부터 9FFFFh 까지의 640KB는 Conventional Memory 라고 불리며 도스에서 응용프로그램이 위치할 수 있는 영역입니다. 실제로는 앞부분의 0h부터 3FFh까지의 400h(1KB)의 영역에는 Real Mode IVT가 존재하며 400h부터 4FFh까지의 100h의 영역에는 BDA(Bios Data Area)로서 사용할 수 없습니다. 또한 7C00h부터 7DFFh까지 200h의 영역에는 부트섹터가 존재합니다. 또한 9FC00부터 9FFFF까지의 400h에는 EBDA(Extended Bios Data Area)로서 사용할 수 없습니다.

이후의 A0000h부터 FFFFFh까지의 384KB는 ROM과 Video RAM 영역으로 사용할 수 없습니다. 이부분은 Upper Memory 혹은 UMBs(Upper Memory Blocks)라는 이름으로 불립니다. 더 자세한 내용은 osdev의 memory map을 참고하시기 바랍니다 (http://wiki.osdev.org/Memory_Map_%28x86%29)

이제, 우리가 관심있는 주제인 HMA로 넘어가겠습니다.

HMA는 High Memory Area의 약자입니다. 이곳은 8086/8088에서 사용할 수 있는 메모리의 최대영역인 1MB 이상의 영역으로서 80286 이상의 기종에서 A20 Gate를 Open함으로써 사용할 수 있습니다. 세그먼트 : 오프셋 방식으로 이 부분의 주소를 표기하면 FFFF:0010부터 FFFF:FFFF 까지 입니다.

아시다시피 8086/8088 에서는 20bit의 어드레스 버스를 사용하기때문에 최대 1MB의 영역에 접근할 수 없습니다. 따라서 세그먼트 : 오프셋 방식으로 최대 FFFF:000F = FFFFFh까지 접근이 가능합니다. 그렇다면, 이 값에서 1이 증가하여 FFFF:0010이 되면 어떻게 될까요? (0x10FFEF이고 0xFF0만큼의 추가 데이터)

비트로 표시하면

1 0000 0000 0000 0000 0000 이 되므로 20bit의 어드레스 버스를 가지는 8086/8088에서는 표시할 수도 없고 인식할수도 없어 사용할 수 없는 값이 됩니다. 그렇다면, 24bit의 어드레스 버스를 가지는 80286에서는 어떨까요? 현재 CPU가 Real Mode에 있다고 가정한다면, 주소 지정 방식으로 이때 어드레스 라인 A0부터 A19까지를 사용하여 세그먼트 : 오프셋 방식으로 최대 FFFF:000F값을 표시할 수 있어 이전의 8086/8088과 호환성을 가집니다.

이전에 80286을 소개하면서도 말했었지만, 80286은 8086과의 호환성(최대 1MB의 메모리)을 보장하기 위해 어드레스 라인중 하나인 A20가 키보드 컨트롤러(8042)와 함께 AND 게이트로 묶습니다. 이 A20 Gate를 통해서 보호모드로 진입하지 않고도, 80286은 HMA로의 접근이 가능합니다. 


 



다시한번 살펴 보겠습니다. 위에서 예시로 들었던 1 0000 0000 0000 0000 0000 문제의 경우, 80286에서는 8086/8088과는 달리 실제 하드웨어상으로는 A20 어드레스 라인이 존재하므로 bit가 On될 수 있습니다. 따라서 다음과 같이 두가지 경우로 나눌 수 있습니다.

1. 세그먼트와 오프셋이 FFFF:0010을 가리키로 A20 Gate가 Off되었을 경우
2. 세그먼트와 오프셋이 마찬가지로 FFFF:0010 을 가리키고, A20 Gate가 On되었을 경우

첫번째 경우에는 값이 FFFFFh를 넘었지만, 20번째 메모리 비트가 Off되었으므로 0 0000 0000 0000 0000 0000 되어 0MB를 가리키게 됩니다. 오버플로우와 비슷한데, 메모리가 이렇게 한도를 넘어 하위 비트로 돌아가는 현상을 Wrap Around라고 합니다.

반대로 A20 Line이 On되어있을경우에는 1 0000 0000 0000 0000 0000 이 되어 1MB이상의 영역을 가리킬 수 있습니다. 물론 현재 CPU는 Real Mode에 있으므로, CPU는 16bit 레지스터를 통해서 0000 0000 0000 0000 0000 (0MB) 영역에 데이터를 쓰려고 하지만 실제로는 A20 Gate가 On되어있으므로 1 0000 0000 0000 0000 0000 영역에 데이터를 쓸 수 있게 되는 것입니다.

결론적으로 CPU는 레지스터상으로 같은 메모리 공간에 값을 쓰려고 하지만, A20 Gate를 통해서 1MB이상의 FFFF:0010 부터 FFFF:FFFF까지의 64KB(실제로는 FFFF:0000이 아니라 FFFF:0010부터 시작하므로 64KB - 16byte)영역에 접근할 수 있습니다. 또한 이 게이트를 Off 함으로써 8086/8088과의 호환성을 유지할 수 있습니다. DOS에서 이와 관련된 파일은 HIMEM.SYS 입니다.

Real Mode가 아닌 Protected Mode에서 A20 Gate는 중요한 역할을 합니다. 한가지 예를 들어 보겠습니다.

만약, 보호모드에서 1MB영역에 접근하려고 한다면 어드레스는 다음과 같습니다.

 1 0000 0000 0000 0000 0000 (1MB) 하지만, A20 Gate가 Off되어있다면
 0 0000 0000 0000 0000 0000 (0MB) 이 되어버리고, 마찬가지로

11 0000 0000 0000 0000 0000 (3MB) 에 접근하려 하는데 A20Gate가 Off되어있다면
10 0000 0000 0000 0000 0000 (2MB) 가 되어버려서 홀수 MB 영역엔 접근할 수 없습니다.


3. A20 Gate On 방법

3가지 방법이 있다.

- A20 게이트와 엮인 키보드 컨트롤러를 조작

- 486부터 지원한 A20 게이트 전용 BIOS 서비스 0x15를 이용

- 시스템 컨트롤 포트를 조작, 즉 Port I/O 를 이용하기

각 방법은 책을 참조 하도록 하자.

 

4. I/O Port

Peripheral Device, 즉 흔히 주변장치라 부르는 것들과 CPU가 데이터를 주고 받기 위해서는

두 가지 방법이 있다.

(참조 - http://shinluckyarchive.tistory.com/237)

 

하나는 Memory Mapped I/O(MMIO), 즉 RAM 상에 일정 영역 디바이스를 위한 메모리를 할당해서

mov 명령을 이용해 디바이스의 데이터를 레지스터로 옮기는 거고

 

다른 하나는 Port Mapped I/O(PMIO), 즉 주변장치를 위한 (RAM상의 주소가 아니라)특별한 주소를 할당하고

그것에 접근하기 위한 명령어를 이용해 레지스터에 데이터를 옮기는 것.

 

각각의 장단점은 여길 참조해라 http://en.wikipedia.org/wiki/Memory-mapped_I/O[각주:1]

 

사실 PMIO, MMIO 방법은 CPU-Device간 직접 통신이기 때문에 Programmed I/O 라고 해석될 수도 있겠다.

근데 내 생각에는 Programmed I/O, PIO는 특정 인터페이스(ATA)를 통한 대량의 데이터 전송이라고 보는게 더 맞겠다.

방식은 위의 두가지를 이용 하겠지만..

자세한건 여길 참조 하셈 http://en.wikipedia.org/wiki/Programmed_input/output[각주:2]

 

PIO는 CPU와 디바이스간 직접 통신하기때문에 CPU가 다른일을 하기 어렵다.

그래서 능률이 떨어지므로, Device에서 메모리로 직접 데이터를 전송하는 방식인 Direct Memory Access, DMA 기술이 도입되었다.

 

(그림1 [각주:3])

자세한 내용은 여길 참조 하셈. http://en.wikipedia.org/wiki/Direct_memory_access[각주:4]

 

5. 추가 자료

 

이건 Bochs 포트 리스트

http://bochs.sourceforge.net/techspec/PORTS.LST

 

C언어로 Port I/O 프로그래밍 하기

http://www.ibiblio.org/pub/linux/docs/howto/IO-Port-Programming

 

I/O Port에 관한 OsDev위키

http://wiki.osdev.org/I/O_Ports 

 

주변장치에 관한 읽을거리

devices.pdf

 


 
  1. http://en.wikipedia.org/wiki/Memory-mapped_I/O [본문으로]
  2. http://en.wikipedia.org/wiki/Programmed_input/output [본문으로]
  3. http://thingsfinder.com/info/dma/ [본문으로]
  4. http://en.wikipedia.org/wiki/Direct_memory_access [본문으로]