메모리 맵 입출력: 두 판 사이의 차이

위키백과, 우리 모두의 백과사전.
내용 삭제됨 내용 추가됨
JongAmPark (토론 | 기여)
편집 요약 없음
JongAmPark (토론 | 기여)
편집 요약 없음
16번째 줄: 16번째 줄:


하지만 메모리 매핑 입출력은 어드레스와 데이터 버스를 무척 많이 사용하게 된다. 그래서 보통 메인 메모리에 접근하는 것보다 매핑된 장치에 접근하는 것이 더 느리다. 반면, 포트 매핑 입출력은 입출력용으로 할당된 버스를 사용할 경우 느리지 않다.
하지만 메모리 매핑 입출력은 어드레스와 데이터 버스를 무척 많이 사용하게 된다. 그래서 보통 메인 메모리에 접근하는 것보다 매핑된 장치에 접근하는 것이 더 느리다. 반면, 포트 매핑 입출력은 입출력용으로 할당된 버스를 사용할 경우 느리지 않다.

==예==

[[8-bit]] [[microprocessor]]로 구현된 간단한 시스템을 가정해보자. 해당 CPU는 16-bit 어드레스 라인을 가지고 있어서, 64[[kibibyte]] (KiB)의 메모리를 억세스할 수있다. 이러한 시스템에서, 어드레스 공간의 첫 32 KiB는 [[random access memory]] (RAM)에 할당되어 있고, 그 다음 16K는 [[read only memory]] (ROM)에 할당되어 있다. 그리고 나머지는 timer나 counter, video display chip, 오디오 발생 장치와 같은 다양한 장치들을 위해서 할당이 되어 있다고 하자. 연결된 장치(device)들은 자기들을 의미하는 주소에 대해서만 반응을 하고, 다른 주소들은 무시를 한다. 이런 것은 address decoding circuit이 하게 되고, 이런 식으로 시스템의 메모리 맵이 만들어진다.

그래서 만들어지게 되는 메모리 맵은 다음과 같을 수있다.

<!-- border="1" cellpadding="1" cellspacing="0" style="font-size: 85%; border: gray solid 1px; border-collapse: collapse; text-align: center; width: 100%" style="background: #ececec;" -->

{| class="wikitable"
|-
! Device
! Address range<br />([[hexadecimal]])
! Size
|-
!RAM
|0000 - 7FFF
|32 KiB
|-
!General purpose I/O
|8000 - 80FF
|256 bytes
|-
!Sound controller
|9000 - 90FF
|256 bytes
|-
!Video controller/text-mapped display RAM
|A000 - A7FF
|2 KiB
|-
!ROM
|C000 - FFFF
|16 KiB
|}

메모리 맵에 빈 공간들이 있다는 점을 주목하자. 이런 것은 흔한 일이다.

자 이제 비디오 컨트롤러의 네번째 레지스터가 화면의 바탕 색깔을 지정하는데 쓰인다고 가정해보자. CPU는, 일반적으로 메모리에 기록하는 명령을 이용해서, A003이라는 메모리 내의 위치에 값을 기록함으로써 배경색을 지정할 수있다. 같은 방법을 이용해서, 비디오 컨트롤러의 특별한 램 공간에 문자를 써서, 화면에 글자를 표현할 수있다. [[비트맵|비트맵 디스플레이]을 사용할 수있도록 만든 싼 [[Random Access Memory|RAM]]이 나오기 전까지는, 이런 식의 캐릭터 쎌 방식을 이용해서 디스플레이하는 것이 대종을 이루었었다. ([[Text user interface]] 참조)


== 불완전한 어드레스 디코딩 ==
== 불완전한 어드레스 디코딩 ==

2008년 2월 20일 (수) 01:38 판

메모리 매핑 입출력(Memory-mapped I/O, MMIO)과 포트 입출력컴퓨터 안의 CPU주변 장치 사이에서 입출력을 수행하는 두 가지의 상호 보완적인 방법이다. 또, 보통 메인프레임 컴퓨터에서 보통 채널이라고 불리는 입출력만 전담하는 프로세서를 사용하는 방법도 있다. 이러한 전담 프로세서는 자신만의 명령어를 가지고 이를 수행한다.

Memory-mapped I/O (memory-mapped file I/O와 혼동하지 말기 바란다.)는 메모리와 I/O 디바이스를 억세스하기 위해, 같은 어드레스 버스를 이용한다. 그리고 메모리를 억세스하기 위한 CPU 인스트럭션을, 디바이스를 억세스하는데도 쓴다. I/O 디바이스를 처리해주기 위해서, CPU의 어드레스 공간중 일부가 I/O를 위해서 할당이 되어야만 하는데, 이렇게 할당하는 것은 일시적일 수도 있고 ( Commodore 64 컴퓨터는 I/O 디바이스와 일반적인 메모리를 뱅크 스위치할 수있었다.), 아니면 영구적일 수도 있다. 각 I/O 디바이스는 CPU의 어드레스 버스를 모니터하고 있다가, CPU가 디바이스용으로 할당된 메모리 공간을 억세스하면 거기에 반응를 보내준다. 그리고 데이터 버스를 의도한 디바이스의 하드웨어 레지스터에 연결해 준다.

Port-mapped I/O는 I/O를 수행하기 위해 특별히 고안된 CPU instruction을 사용한다. 이 방식은 보통 Intel microprocessors에서 구현되어 있다. 인텔 프로세서에는 IN과 OUT이라는 명령어가 있는데, 이것은 I/O 디바이스에 1 byte를 읽고/쓰기 위한 것이다. 또한 I/O 디바이스는 일반적인 메모리 공간과 별도로, 독립된 어드레스 공간을 가진다. 이것의 구현은 CPU의 물리적 인터페이스에서, 특별히 준비된 "I/O" pin을 이용해서 구현되거나, 혹은 I/O 전담으로 쓰이는 bus를 이용해서 구현된다.

한 디바이스의 direct memory access (DMA)는 그런 CPU와 디바이스간의 통신 방법에 영향을 받지 않는다. 특히 메모리 매핑에 영행을 받지 않는다. 이것은 DMA가 CPU를 통하지 않는, 메모리와 디바이스간의 직접적인 통신 방법이기때문이다.

하드웨어 인터럽트는 CPU와 주변 장치간에 통신을 하는 또 하나의 방법이다. 하지만, 이러저러한 이유로 좀 다르게 취급된다. 앞서 살펴본 방법과 달리, 이 방식은 디바이스가 요청을 하는 것이다. 그리고 단방향 통신이다. 즉 정보가 디바이스에서 CPU로만 흐른다는 것이다. 마지막으로 각 인터럽트 라인은, "인터럽트가 발생했다"라는 식으로 고정된 의미를 갖는 단 한 bit의 정보만을 가지게 된다.

두 입출력 방식의 상대적인 장점들

포트 매핑 입출력을 사용할 때 얻을 수 있는 가장 큰 장점은 어드레싱 능력이 제한된 CPU를 사용할 때 나타난다. 포트 매핑 입출력이 입출력 접근을 메모리 접근과 분리하기 때문에 메모리용으로 주소 영역 전체를 사용할 수 있다. 또다른 장점은 어셈블리어로 된 소스 목록을 볼 때, 언제 입출력이 수행되는지를 알아보기가 쉽다. 이는 바로 입출력용으로만 쓰는 명령어를 써서 입출력을 수행하기 때문이다.

메모리 매핑 입출력을 사용하는 장점은, 포트 입출력을 구현할 때 필요한 부수적인 복잡성이 없어지기 때문에, CPU는 내부 로직이 덜 필요하고, 그러므로 더 저렴하고, 더 빠르고, 더 쉽게 CPU를 만들 수 있다는 것이다. 바로 이 점은 RISC가 추구하는 바와 그 노선을 따르는 것이고, 이런 방식은 임베디드 시스템을 구현할 때 장점으로 작용한다. 16비트 CPU 구조가 없어지고, 32비트64비트 구조로 대치되어 감에 따라, 입출력 장치를 위해 메모리 맵 일부를 확보해 놓는 것은 더 이상 문제가 되지 않는다.[출처 필요] 그리고 장치를 어드레싱하기 위해서 일반적인 메모리 명령어를 사용한다는 것은 메모리뿐 아니라 입출력을 위해서도 모든 CPU 어드레싱 모드가 다 지원된다는 것을 의미한다.

하지만 메모리 매핑 입출력은 어드레스와 데이터 버스를 무척 많이 사용하게 된다. 그래서 보통 메인 메모리에 접근하는 것보다 매핑된 장치에 접근하는 것이 더 느리다. 반면, 포트 매핑 입출력은 입출력용으로 할당된 버스를 사용할 경우 느리지 않다.

8-bit microprocessor로 구현된 간단한 시스템을 가정해보자. 해당 CPU는 16-bit 어드레스 라인을 가지고 있어서, 64kibibyte (KiB)의 메모리를 억세스할 수있다. 이러한 시스템에서, 어드레스 공간의 첫 32 KiB는 random access memory (RAM)에 할당되어 있고, 그 다음 16K는 read only memory (ROM)에 할당되어 있다. 그리고 나머지는 timer나 counter, video display chip, 오디오 발생 장치와 같은 다양한 장치들을 위해서 할당이 되어 있다고 하자. 연결된 장치(device)들은 자기들을 의미하는 주소에 대해서만 반응을 하고, 다른 주소들은 무시를 한다. 이런 것은 address decoding circuit이 하게 되고, 이런 식으로 시스템의 메모리 맵이 만들어진다.

그래서 만들어지게 되는 메모리 맵은 다음과 같을 수있다.


Device Address range
(hexadecimal)
Size
RAM 0000 - 7FFF 32 KiB
General purpose I/O 8000 - 80FF 256 bytes
Sound controller 9000 - 90FF 256 bytes
Video controller/text-mapped display RAM A000 - A7FF 2 KiB
ROM C000 - FFFF 16 KiB

메모리 맵에 빈 공간들이 있다는 점을 주목하자. 이런 것은 흔한 일이다.

자 이제 비디오 컨트롤러의 네번째 레지스터가 화면의 바탕 색깔을 지정하는데 쓰인다고 가정해보자. CPU는, 일반적으로 메모리에 기록하는 명령을 이용해서, A003이라는 메모리 내의 위치에 값을 기록함으로써 배경색을 지정할 수있다. 같은 방법을 이용해서, 비디오 컨트롤러의 특별한 램 공간에 문자를 써서, 화면에 글자를 표현할 수있다. [[비트맵|비트맵 디스플레이]을 사용할 수있도록 만든 싼 RAM이 나오기 전까지는, 이런 식의 캐릭터 쎌 방식을 이용해서 디스플레이하는 것이 대종을 이루었었다. (Text user interface 참조)

불완전한 어드레스 디코딩

장치가 어드레스를 완전히 디코딩할 수도 있고, 아니면 불완전하게 디코딩할 수도 있다.

  • 완전히 디코딩을 할 경우 주소 버스의 모든 라인을 검사하게 되는데, CPU가 매핑되지 않은 메모리 영역에 접근하면 오픈 데이터 버스 상태를 야기한다.
  • 불완전한 디코딩, 혹은 부분 디코딩이라고 하는 방법은 주소 일부분을 검사하는, 더 간단하고 대체적으로 단순한 로직을 사용한다. 이러한 간단한 디코딩 회로는 장치가 여러 개의 다른 어드레스에 반응을 할 수 있게 하거나, 메모리 맵의 다른 곳들에 해당 장치의 가상본을 효과적으로 만들 수 있게 도와 준다. 이 때, 이 가상본들은 모두 똑같은 실제 장치를 가리키게 된다. 그러므로 보통은 이러한 방식을 쓴다고 하여 특별히 좋을 것은 없다. 다만, 디코더를 단순하게 만들 수 있다는 장점이 있다. 보통 디코딩하는 그 로직 자체는 프로그래밍으로 짤 수 있기 때문에, 시스템이 필요에 따라 메모리 맵을 다시 설정할 수 있다.

참고 문서