728x90
MMU 한눈에: 개요와 핵심 개념 (시리즈 1/3)
요약
- MMU(Memory Management Unit)는 가상 주소(VA)를 물리 주소(PA)로 변환하고, 접근 권한과 메모리 속성을 검사해 프로세스 격리와 메모리 보호를 제공합니다.
- 이 글은 MMU의 역할, 기본 용어, 동작 흐름을 쉬운 예시와 그림으로 설명합니다.
(그림) MMU 전체 구조

목차
왜 MMU가 필요한가?
기본 용어 정리
MMU의 동작 흐름(쉽게)
실무에서 자주 보는 개념: TLB, 페이지, 페이지 테이블
다음 글 예고: 내부 구조와 ARM 특성
왜 MMU가 필요한가?
- 프로세스 격리: 각 프로세스가 서로의 메모리를 덮어쓰지 못하도록 함.
- 보호: 커널 메모리는 유저 모드에서 읽기/쓰기/실행 못 하게 설정.
- 가상 메모리: 물리 메모리보다 큰 주소 공간 제공(스왑 등).
- 메모리 속성 관리: 캐시/비캐시, Device 영역 제어.
간단한 비유
- 도서관의 색인 카탈로그: 사용자가 찾는 책(가상 주소)을 실제 선반(물리 주소) 위치로 찾아주는 역할. 자주 찾는 책은 계산해 놓은 책꽂이(=TLB)에 저장.
- 기본 용어 정리 (요약)
- 가상 주소(VA) / 물리 주소(PA)
- 페이지(page): 일반적으로 4KB 등, 변환의 최소 단위
- 페이지 테이블(Page Table) / PTE
- TLB(Translation Lookaside Buffer): 변환 캐시
- ASID: 주소 공간 식별자
- MMU의 동작 흐름(한 번에 보기)
1. CPU가 VA로 접근.
2. MMU가 TLB에서 매핑을 찾음.
있으면 PA로 바로 접근.
없으면 페이지 테이블을 조회해서 PTE를 얻음
3. PTE의 권한/속성 검사.
- 실패하면 페이지 폴트(예외).
4. 변환 결과를 TLB에 저장하고 메모리에 접근.
핵심 개념 짚기
- TLB miss가 비용으로 이어짐 → hugepage, ASID 전략 고려.
- 페이지 크기 선택(4KB vs 2MB 등)은 TLB 부담과 단편화의 절충.
- 페이지 테이블은 다단계(레벨) 구조가 일반적.
- 실무에서 자주 보는 개념: TLB, 페이지, 페이지 테이블
이 섹션에서는 개발·디버깅·성능 최적화 관점에서 흔히 마주치는 개념들을 실무 중심으로 정리합니다.
4.1 TLB (Translation Lookaside Buffer)
- 역할: VA → PA 변환 결과(주로 상위 PFN과 몇몇 속성)를 캐시해서 주소 변환 비용을 크게 줄여 줍니다.
- 왜 중요한가:
- TLB miss가 발생하면 MMU는 다단계 페이지 테이블을 조회해야 하므로 지연이 큽니다(메모리 접근 수십~수백 배 비용).
- 반복적인 메모리 접근 패턴에서 TLB hit 비율은 성능에 직접적인 영향을 줍니다.
- 실무 포인트:
- 큰 페이지(hugepages, 2MB/1GB 등)를 사용하면 TLB 엔트리 당 커버하는 메모리 범위가 늘어나 TLB miss가 줄어듭니다. 그러나 내부 단편화와 메모리 사용의 유연성 손실이 생깁니다.
- 멀티스레드/멀티프로세스 환경: 컨텍스트 스위치 시 TLB를 플러시하면 성능이 떨어집니다. ASID가 있으면 각 주소 공간의 엔트리를 구분해 플러시를 줄일 수 있습니다.
- 멀티코어 시스템: 페이지 테이블 변경 시 각 코어의 TLB를 동기화(“TLB shootdown”)해야 하므로 비용 발생. 이 부분이 NUMA/대규모 서버에서 성능 병목이 되기도 합니다.
- 관찰 방법:
- Linux: perf stat -e cpu/cache-misses, dTLB_load_misses 등을 이용해 TLB miss 관련 이벤트를 볼 수 있음. (하드웨어/커널 버전 따라 이벤트 이름 다름)
- 커널 개발: /proc/kpageflags, /proc/pid/pagemap 등을 통해 페이징 동작을 분석.
4.2 페이지(Page)와 페이지 크기
- 페이지란: 가상-물리 변환의 기본 단위(가장 흔한 크기: 4KB).
- 페이지 크기가 중요한 이유:
- 작은 페이지(4KB)는 메모리 할당의 세분화에 유리하지만, TLB 압박이 큼.
- 큰 페이지(2MB/1GB 등)는 TLB 부담을 줄여 성능을 올리지만 내부 단편화(메모리 낭비) 위험이 있음.
- 용도별 선택:
- 데이터베이스, HPC, 가상화: 메모리 접근 패턴이 크고 연속적이면 hugepage 사용 권장.
- 일반 애플리케이션: 기본 4KB로 충분한 경우가 많음.
- 실무 팁:
- Linux에서 transparent hugepage(THP) 기능으로 자동으로 2MB 페이지를 만들기도 함. 성능 프로파일링으로 장단점 판단 필요.
- 페이지 정렬/할당 정책(예: vmalloc vs kmalloc, get_free_pages의 order)을 이해하면 커널 메모리 이슈 파악에 도움.
4.3 페이지 테이블(Page Table)
- 다단계 구조:
- 다단계(page table levels)는 큰 가상 주소 공간을 적은 메모리로 표현하기 위해 사용합니다(L0/L1/L2/...).
- 각 레벨 엔트리는 다음 레벨 테이블의 물리 주소이거나 최종 물리 페이지를 가리킵니다(“block” 엔트리 가능).
- PTE (Page Table Entry) 주요 필드(개념적):
- Output Address (물리 페이지 프레임 상위 비트)
- Valid bit / Table bit (다음 레벨 테이블을 가리키는지 여부)
- AP (Access Permission) — 읽기/쓰기/특권 구분
- AF (Access Flag) — 페이지가 접근되었는지 표시
- Dirty bit — 쓰기 발생 여부
- AttrIndex / MAIR 인덱스 — 캐시/Device 속성 결정
- XN / UXN (실행금지 비트)
- 실무에서 확인·디버깅하는 방법:
- 사용자 관점:
- cat /proc/self/maps 또는 /proc/
/maps: 가상 메모리 영역(프로세스의 메모리 맵) 확인. - /proc/
/pagemap: 가상 페이지와 물리 프레임 매핑(원시 데이터, 루트 권한 필요).
- cat /proc/self/maps 또는 /proc/
- 커널/부트 관점:
- 부트 초기에는 identity map(가상==물리)을 사용해 초기화가 단순해짐. 이후 정식 페이지 테이블로 전환.
- 커널 로그(dmesg)에 초기 MMU/TTBR/TCR/MAIR 설정 값을 찍어 두면 부트 문제 추적에 유리.
- 성능 고려사항:
- 페이지 테이블의 메모리 접근(테이블 워크)은 캐시 친화적으로 설계되어야 함. 즉, 페이지 테이블 자체가 잘 캐시되도록 엔트리 배치·정렬을 고려.
- PTE 크기(예: 8바이트)와 페이지 테이블 전체 크기에 따라 메모리 오버헤드가 달라짐. 64-bit 시스템에서는 페이지테이블 메모리 비용이 커질 수 있음.
- 사용자 관점:
- 안전성/보안:
- Execute Never (XN) 등의 비트를 활용해 데이터 영역의 코드 실행을 방지(W^X 정책).
- 사용자-커널 분리를 통해 취약점으로 인한 권한 상승을 방지.
- 다음 글 예고
- 다음 포스트(시리즈 2)에서는 페이지 테이블 구조와 PTE 필드, 권한 비트, 캐시 속성(MAIR) 등 내부를 자세히 다룹니다.
참고 및 읽을거리
- ARM Architecture Reference Manual (MMU 섹션)
저자 노트: 이 글은 초심자도 개념을 빠르게 이해하도록 의도했습니다. 다음 글에서 페이지 테이블 레이아웃과 ARM 특화 레지스터(TTBR, TCR, MAIR, SCTLR 등)를 시각적으로 풀어드릴게요.