ARM 프로세스는 주변장치에 접근하기 위해서는 memory mapped I/O 방식을 사용합니다.
x86계열과는 다르게 별도로 instruction이 존재하는 것이 아니라 주변 장치를 위해 필요한 모든 정보(register ...)들이 모두 메모리에 위치하게 됩니다. 이때 물리적 메모리(physical memory)를 논리적 메모리(logical memory)로 매핑해주는 MMU(Memory Management Unit) 의 기능이 OS가 부팅될때 활성화되므로 단지 우리는 해당하는 register가 메모리 어느 번지에 위치하는지 테이블만 보고 해당 작업을 해주면 끝입니다. 사실 Linux Driver를 만든다는 것이 따지고 보면 이런 작업을 좀더 쉽게 함수로 제공해 주는 것 정도라고 봐야겠죠. 하지만 모든 일이 그렇듯이 먼저 이런 일을 해 준 사람에게 고마워해야 할겁니다.
ARM에서는 주변장치라는 말 대신 GPIO(General Purpose Input/Output ) pin 이라는 말을 많이 합니다. 주변장치에 접근하는 하나의 방식이지만 현재는 거의 모든 주변장치에 대해서 GPIO 방식을 이용하는 것으로 보입니다. 하드웨어적으로 하나의 pin으로 존재하는 것에 대해서 GPIO에서는 여러가지 방식으로 접근을 합니다. 가장 기본적인 것이 해당 pin에서 데이터를 읽을 것인가 쓸 것인가(Read/Write)를 결정하는 register가 존재하고, 읽고 쓰는 실제 데이터가 위치하는 register가 존재합니다. 쓰기 작업은 Read Modify Write (RMW) 방식으로 차례대로 진행되는 것이 대부분입니다. 즉, 출력용 주변 장치는 RMW 방식으로 접근하면 되는 것이죠. 그에 비해서 읽기 작업은 Read만 하면 되니 상대적으로 쉽습니다.
실제적으로 프로그래밍을 할때 주변장치에 접근하는 방식은 x86과는 사뭇 다릅니다. 앞에서 언급한바와 같이 별도의 instruction이 존재하는 것이 아니기 때문에 처음 접할때는 상당히 당혹스럽습니다. linux에서는 기본적으로 user level에서 접근할수 있는 방식은 /dev/mem을 직접 접근하는 방식입니다. 이 파일을 mmap() 함수를 이용해서 접근하는 방식이죠. 이후 작업은 대개 비트 연산과 같은 저레벨의 연산 작업을 수행하는 것이 전부입니다. 여기서 주의해야 할 사항은 다음과 같습니다.
- /dev/mem 을 열때 O_SYNC flag 사용할것(cash 기능을 없앱니다.)
- 주요 변수에 volatile 키워드를 사용합니다. 이 역시 cash 기능에 따른 부작용을 없애게 됩니다.
주변장치에 접근하는 방식을 이해하는 것은 소스 파일을 보는 것 만큼 쉬운 방법이 없을 겁니다. ftp://ftp.embeddedarm.com/ts-arm-linux-cd/samples/ 에 있는 파일들이 모두 주변 장치에 접근하는 소스 파일들입니다. 가장 쉬운 것이 jp.c 로 단지 Read 기능 만으로 점퍼의 상태를 알수 있습니다. button.c는 소스 중간에 위치한 while() 문만 주석처리하면 led 점멸을 볼 수 있습니다. 즉, Write 기능을 확인할수 있죠. 이 두개파일만 컴퓨터 구조론 공부할때 배운 내용과 잘 접목시켜서 원리를 이해한다면 x86에서는 느껴보지 못한 희열(?)을 느낄수 있을겁니다. RISC 라는 말이 나온것도 같은 맥락으로 생각하시면 되겠죠. 굳이 주변장치를 접근하는데 instruction을 이용할 필요는 없는 셈이죠. 나머지 소스파일도 잘 봐두면 도움이 됩니다. 요것들이 NetBSD에서는 Driver로 지원을 하거든요~~
여기까지 이해를 했으면 이제는 http://www.embeddedarm.com/downloads/Components/EP9301_User_Guide.pdf 의 EP9301 User's Guide(EP9032 User's Guide는 cirrus 측에서 제공하고 있지 않습니다.) 와 http://www.embeddedarm.com/Manuals/ts-7200-manual-rev2.2.pdf 의 TS-7200 Hardware 메뉴얼을 잘 읽어보는 일만 남았습니다. 두 문서에서 메모리맵에 대한 정보를 잘 비교하면 TS-7200에서 어떤 기능을 구현하고 있는지에 대해서 알수 있습니다.
- EP9301 User's Guide: 2.3.6 Internal Register Map
- TS-7200 Hardware Manual: appendix B Memory and Resister Map
Reference) http://www.simtec.co.uk/appnotes/AN0014/
ps) 너무 글을 두서없이 일기처럼 쓰다보니 정신이 없네요. 한번 예쁘게 PDF 파일로 한번 정리를 해봐야겠습니다.
댓글 없음:
댓글 쓰기