MMU, TLB, Page Table
여러 프로세스들이 메모리를 할당받을때 충돌이 나게 되면, 1 프로세스의 코드를 2가 덮어버린다거나 침범해버리는 문제가 발생할 수 있다.
그래서 그 문제를 해결하기위해서 운영체제는 각 프로세스들이 독립적인 메모리 공간을 갖도록 할당을 해주게 된다.
전체 그림이 약간 이렇게 되어있는데
cpu -> 가상주소 -> MMU -> TLB 확인 -> Page Table -> 물리주소 변환 -> 메모리 접근
한번 알아보겠다
MMU(Memory Management Unit) #
가상 주소를 물리 주소로 변환해주는 하드웨어다.
하드웨어 cpu 내장 또는 외부칩 계층에 존재하며 주소 변환기라고 생각하면 편하다.
운영체제는 각 프로세스에게 전체 메모리를 혼자 연속적인 공간을 쓰는것 처럼 보이게 하는것이고
사실상 물리적으로는 분리되어있다. 그러나 가상 메모리라는 표현방식을 통해서 그렇게 보이게 하는건데
이 가상 메모리 주소를 읽고 물리 주소로 변경해주는 역할을 생각하면 되겠다.
Page Table #
운영체제가 관리하는 가상 주소 - 물리 주소 매핑 정보 테이블로 보통 페이지 크기는 4kb 단위다.
| 가상 페이지 번호 | 물리 프레임 번호 | 보호비트 | 유효비트 |
|---|---|---|---|
| 0x00001 | 0x00A3 | RW | 1 |
| 0x00002 | 0x00A4 | RO | 1 |
| 0x00003 | — | — | 0 (페이지 미적재) |
위 처럼 각 프로세스마다 자기만의 페이지 테이블이 존재하며 유효 비트가 0이면 page fault (접근 불가)를 발생시켜 보호한다.
보호 비트 (read/write/execute)로 접근 권한도 제어한다.
여기서 주소변환 절차 (mmu 내부 동작)을 살펴보면 가상 주소는 보통 다음과 같이 구성된다.
( 가상 페이지 번호 \ 페이지 내 오프셋)
- cpu가 가상 주소를 생성한다 ex.
0x7FFE1234 - MMU가 페이지 번호를 추출한다. 0x7FFE
- TLB에 검색한다 (뒤에서 설명함)
- 없으면 page table에서 확인한후에 물리 프레임 번화를 확인한다
- TLB에 캐시한다. (tlb는 쉽게 말해 주소 캐시 역할)
- 물리 주소 조합
- 실제 메모리에 접근한다.
물리주소는 (물리프레임번호 << 페이지 오프셋) + 오프셋
보호 메커니즘
운영체제와 하드웨어는 다음과 같은 규칙을 둔다.
- 커널 모드 / 사용자 모드 분리
- 사용자 프로그램은 커널 영역 접근 금지
- 시스템 콜을 통해서만 요청 가능
- 페이지 보호 비트 (Protection Bit)
- 각 페이지에는 읽기(R), 쓰기(W), 실행(X) 권한이 있음
- 코드 영역은 “읽기+실행”, 데이터는 “읽기+쓰기”로 설정
- 페이지 폴트(Page Fault)
- 잘못된 주소 접근 시 CPU가 인터럽트를 발생시키고,
- OS가 프로세스를 중단시키거나 필요한 페이지를 적재
TLB(Translaction Lookaside Buffer) #
mmu 내부에 있는 고속 캐시 메모리로 최근 변환된 가상 페이지 -> 물리 프레임 정보를 저장한다.
cpu 접근 시 거의 항상 tlb를 먼저 조회한다 일반적으로 tlb 적중률은 95퍼 이상이라 한다.
Page Table 계층화 #
multi level page table이라고도 불리는데 모든 가상주소에 대해 1:1로 테이블로 만들면 너무 크다.
그래서 계층형 구조를 쓰는데 예를들어 32비트 주소를 4kb로 나누면
총 페이지 수 2^32 / 2^12 = 1,048,576개로 각 페이지 엔트리가 4바이트면 4mb 테이블이 필요하다.
(2^32 = 전체 주소 공간 크기 32비트 주소라면 2^32 주합이 가능 = 4gb)
page size는 4kb 단위로 (2^12)임. 이건 모르면 헷갈릴만함.
그래서 다음과 같이 2단계 혹은 4단계 구조로 나눈다 현대 x86-64 에서는 4단계 page table을 사용함.
가상주소 = [P4 | P3 | P2 | P1 | Offset]
-> 단계별로 탐색해 내려가며 물리 주소를 찾아냄.