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 기술이 도입되었다.
자세한 내용은 여길 참조 하셈. 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
주변장치에 관한 읽을거리