본문 바로가기
엠엠유(MMU)를 인에이블(Enable)하려면?


뭘 알아야 이해를 하지

엠엠유 없이는 캐시가 존재할 수 없으며, 캐시는 엠엠유를 통해 많은 일들을 할 수가 있죠. 임베디드 시스템의 시피유가 대부분 가지고 있는 것은 아니며 캐시 존재 유무와 캐시 용량 또한 시피유마다 다르답니다.
"201 유닛" 과 "202 유닛"에 보면 코프로세서, 엠엠유 그리고 캐시 메모리에 대해 이론적인 설명들은 앞에서 다루었으니 엠엠유를 사용하기 위해서 어떻게 프로그램을 하면 되는지 알아보아요.

엠엠유는 코프로세서를 통해 제어할 수가 있죠. 암 코어가 코프로세서를 제어하는 명령어는 두 가지인데 MRC명령어와 MCR명령어랍니다. MCR(Move from register to coprocessor) 명령어는 암 코어 레지스터① 값을 코프로세서 레지스터②로 쓰기 명령이고, MRC(Move from coprocessor to register) 명령어는 코프로세서 레지스터② 값을 암 코어로 레지스터①로 읽어오는 명령어랍니다.

CP15②가 코프로세서인데, MMU Enable을 하기 위해서는 코프로세서 레지스터 중 CR 레지스터(C1)를 제어하면 된답니다.

실제 명령어는,

mcr p15,0x0,r0,c1,c0,0x0

암코어 R0 레지스터 값을 코프로세서 C1 레지스터에 쓰기를 한다는 의미이죠.
이 명령어가 실행됐을 때 하드웨어 디버거로 살펴보면 아래와 같고, M이 바로 MMU를 의미하고 Enable이 됐답니다.

그럼 이제 MMU가 Enable이 됐으면 주소 체계가 바뀌겠죠?

하지만 MMU을 Enable 한다고 해서 모든 설정이 끝난 것이 아니랍니다. Enable을 하기 전에 반드시 해줘야 되는 3가지가 있답니다.
첫 번째, 엠엠유 페이지 테이블(MMU Page Table)이 위치할 주소를 지정해야 해요. 엠엠유 페이지 테이블이란 가상 주소를 물리적 주소를 변환하는 테이블인데요, 개발자가 반드시 주소 지정을 해야 한답니다. 암 코어는 엠엠유가 ON이 되고 나면 가상 주소를 접근하게 되는데 실제 프로그램 코드는 물리적 주소에 있기 때문에 엠엠유 테이블을 통해서 연결시켜 준답니다.

이 테이블 위치를 알려 주기 위해서는 코프로세서 레지스터 중에 TTB(Translation Table Base address,C2) 레지스터가 사용된답니다.

실제 명령어는,

mcr p15,0x0,r0,c2,c0,0x0

암코어 R0 레지스터 값을 코프로세서 C2 레지스터에 Write를 한다는 의미이죠. TTB는 주소를 지정해 줘야 하는데 에스디램의 물리 주소 중에 .Text와 .Data 영역을 사용되지 않는 곳으로 지정하면 되요.

두 번째는 가상 주소와 물리 주소 설정을 해야 해요. 이제 테이블의 시작 주소를 알려 줬으니, 가상 주소를 물리 주소로 변환 시키는 설정이 필요하죠. 씨 언어 프로그램으로 표현한다면 아래와 같아요.

MMU_SetMTT(0x00000000,0x000f0000,0x00000000,RW_CNB);
MMU_SetMTT(0x00200000,0x002f0000,0x00200000,RO_CNB);


첫 번째 인자 값은 가상 주소의 시작, 두 번째 인자값은 가상 주소의 끝 주소, 세 번째 인자 값은 물리 주소 시작, 마지막으로 속성이랍니다. 속성은 퍼미션과 캐시에 관련된 내용이랍니다. 여기서 퍼미션은 가상주소를 접근할 때 Read Only, Read/Write, noaccess 라고 지정이 가능하답니다. 캐시에 관련된 내용은 309 유닛에서 살펴볼께요.

자. 이제 엠엠유 페이지 테이블이 만들어졌군요.


MMU_SetMTT(0x00000000,0x000f0000,0x00000000,RW_CNB)
이 처럼 프로그램을 하면 ③번 같은 값이 만들어 진답니다. 이 값을 보고 ①과 같은 테이블을 만들어내죠. 그리고 속성에서 퍼미션을 지정했는데 ⑤ 처럼 P(SVC,IRQ,FIQ,Abort, SYS,Und)와 U(Usr) 로 나누어져 읽기, 쓰기 권한을 가지게 된답니다.
MMU_SetMTT(0x00200000,0x002f0000,0x00200000,RO_CNB)
이 처럼 프로그램을 하면 ④번 같은 값이 만들어지고, ②와 같은 테이블을 만들며, ⑥ 처럼 P는 읽기/쓰기이며 U는 읽기전용으로 된답니다.

여기서 ③, ④ 값을 보고 어떻께 엠엠유 테이블이 만들어 질까요? 누가 이런 일을 할까요?
인스트럭션 엠엠유와 데이타 엠엠유 내에 TLB라는 친구가 있지요. 이 친구가 열심히 일을 해서 엠엠유 테이블을 만들어 준답니다.
이 친구가 효율적으로 열심히 일을 하기 위해서는 체계적인 규칙이 필요하죠. 크게 3가지로 구분할 수가 있답니다. 섹션, 코어스, 파인이고 기준이 되는 것은 사이즈⑧ 랍니다.
섹션(Section)은 1MB 단위로 주소를 지정하며, 코어스(Coarse)는 64KB와 4KB로 나눌 수가 있고 파인(Fine)는 64KB, 4K, 1KB로 나눌 수가 있답니다.
엠엠유 테이블에서 ①의 Size가 0x100000이니깐 섹션을 사용했군요. 정말 그런지 확인 작업 들어가보죠. ③의 데이타 값이 0000 0C1A이고 다시 32bit로 표현을 하면,

이제 아래의 그림을 보며 비교해 보죠. [1~0] 비트 값이 10으로 끝나면 섹션이니깐 맞네요. ㅎㅎ

[31~20] 비트 값은 주소를 나타내는데 바로 물리 주소를 표현한답니다.
③의 데이타 값에서 [31~20]까지 모두 0x0이니깐 물리주소 시작은 0x0이며, 섹션 size가 1MB(0xFFFFF)이깐 마지막 주소는 0xFFFFF까지 된답니다. 이렇게 해서 ①의 주소가 나왔답니다.
④의 데이타 값에서 [31~20]까지 모두 0x2이니깐 물리주소 시작은 0x200000(0x2이후 모두 0x0으로 채움)이며, 섹션 size가 1MB(0xFFFFF)이깐 마지막 주소는 0x2FFFFF까지 된답니다. 이렇게 해서 ②의 주소가 나왔답니다.

세 번째는 도메인과 퍼미션 지정이랍니다. 코프로세서 레지스터 중에 DACR(Translation Domain Access Control Register,C3) 레지스터가 사용된답니다.

실제 명령어는,

mcr p15,0x0,r0,c3,c0,0x0

암코어 R0 레지스터 값을 코프로세서 C3 레지스터에 Write를 한다는 의미이죠. DACR레지스터는 2비트씩 16개로 나누어 별로도 속성관리를 할 수 있도록 되어 있지요.

2Bit를 가지고 4개의 상황이 있지요.
Domain 의미 설명
00 No Access 모든 access에 대하여 domain fault 발생
01 Client TLB entry의 AP(Access Permission) 비트 정보를 따른다.
10 Reserved Reserved (No Access)
11 Manager TLB entry 의 AP(Access Permission) 비트 정보를 무시하고 무조건 access를 허용한다.

③의 데이타 값에서 [8~5]까지 0x0이니깐 D15~D0 중에 D0가 선택이 됐으며, D0값이 Client랍니다.

Client 의미는 AP 정보를 따른다고 했으니, AP는 [11~10] 비트이며 2Bit를 가지고 있군요. AP도 2Bit를 가지고 있으니 4개의 상황이 있는데, 여기서 추가적인 2개의 비트가 더 있어요. 바로 S와 R 비트랍니다.

이제 AP의 2bit와 R과 S 비트를 종합 정리를 해 보면,


③의 데이타 값에서 AP[11~10]은 11 그리고 R과 S는 00이면, ⑤ 처럼 P: Read/Write U: Read/Write가 되네요.

이제 씨 언어로 프로그램을 만든다면 아래와 같이 하시면 됩니다.


코프로세서 “201” 캐시메모리 “202” “309”




 Season 1의 MMU를 완전 베껴 보자 - Memory Management Unit 과 곁들여 보시면 재미있을 것 같아요. ^^

Linked at 친절한 임베디드 시스템 개발자.. at 2010/07/12 09:00

... sp; 307 소스레벨 디버깅이 뭐죠? 308 엠엠유(MMU)를 Enable 하려면? 309 와치독 타이머(Watchdog Reset)가 뭐죠? 4장 RTOS 아나토미 &nbsp ... more

Commented by Joy at 2010/07/12 09:07
아싸...1등...선리플입니다. ㅋㅋㅋ 1등으로 달아보고 싶었어요
Commented by soto at 2010/07/13 09:18
아...^^;
축하축하~~!!
Commented by Joy at 2010/07/12 09:23
우왕.. mmu tutorial이네요... ㅋㅋㅋ 어쩜 이렇게 깔끔하게..
역시 soto님의 깔끔한 설명은 우주괴수 수준이세요...
Commented by soto at 2010/07/13 09:19
앗...그 정도는 아닌데..
정말 감사요~~!!!
Commented by ruring at 2010/07/20 11:39
자료에 공을 많이드리시는 ㅎㅎ
Commented by soto at 2010/07/22 09:28
네..^^;
제가 좋아하는 글 중에 "조금 더의 차이가 큰 차이 이다" 랍니다.
이왕 글 쓰는거 최선을 다해 보려구여~~!!
Commented by 성수현 at 2010/07/24 11:43
어려운 내용 잘 설명해 주셨습니다. ^^
Commented by soto at 2010/08/03 08:14
하하..
감솨요~!!!
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.
친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -