Virtual Address
64-비트 가상 주소는 다음과 같은 구조이다
| |
헤더 include/threads/vaddr.h, 그리고 include/threads/mmu.h는 가상 주소들에서 작동하는 이러한 함수들과 매크로들을 정의한다. (offset : 상대주소(relative address), 동일 오브젝트 안에서 오브젝트 처음부터 주어진 요소나 지점까지 변위차를 나타내는 정수형)
| |
비트 index(0) 그리고 비트의 수(12개)는 각자 가상 주소의 offset part이다.
| |
page offset bit mask는 1, 나머지 set 는 0
| |
페이지 사이즈는 바이트 (4,096)
| |
가상 주소 va에서 page offset을 추출해 반환
| |
가상 주소 va에서 page number를 추출해 반환
| |
va 가 내부를 가리키는 가상 페이지의 시작지점 반환. 다시 말해, va with the page offset을 0으로 맞춤
| |
가장 가까운 page boundary 까지 rounded up한 va 반환
Pintos에서 가상 메모리는 두 지역으로 나뉘어진다. 유저 가상 메모리와 커널 가상 메모리
그들 사이의 경계는 KERN_BASE:
| |
커널 가상 메모리의 기본 주소. 기본 설정은 0x8004000000. 유저 가상 메모리는 가상 주소 0에서
KERN_BASE. 커널 가상 메모리 가상 주소 공간의 나머지를 차지한다.
| |
va가 각 유저 가상 주소 혹은 커널 가상 주소면 참, 아니면 거짓 반환
x86-84는 받은 실제 물리적 주소로 메모리에 직접적으로 접근하는 어떤 방법도 제공하지 않는다. 이 능력은 보통 운영체제 커널에 필요하기에, Pintos는 커널 가상 메모리를 실제 물리적 메모리에 일대일 대응으로 mapping 하는 방식으로 작동한다. 즉, KERN_BASE 라는 가상주소는 실제 주소 0에 접근하고, 가상 주소 KERN_BASE + 0x1234는 실제주소 0x1234에 접근하는 방식이 계속해서 기계의 실제 물리적 메모리 크기의 따라 계속된다. 따라서, KERN_BASE를 실제 주소에 더하여서 그 주소에 접근하는 커널 가상 주소를 얻을 수 있다. 정반대로, KERN_BASE를 커널 가상 주소에서 뽑아내어서 그에 상응하는 실제 주소를 얻을수 도 있다.
헤더 include/threads/vaddr.h는 이러한 ‘번역’을 해주는 함수 짝을 제공한다.
| |
실제 물리적 주소 pa에 상응하는 커널 가상 주소를 반환한다. 이 pa는 0과 실제 메모리의 바이트 수 의 사이 값이여야 한다.
| |
va에 상응하는 실제 물리적 주소를 반환한다. va는 반드시 커널 가상 주소여야 한다.
헤더 include/threads/mmu.h는 페이지 테이블에 대한 operation을 다음과 같이 제공한다:
| |
각각, PTE(Page Table Entry)가 유저나 커널이 소유하는 것인지 묻는다.
| |
PTE(Page Table Entry)가 가리키는 가상 주소가 writable한지 묻는다.
| |
PML4 하위에 있는 각각 타당한 entry에 auxiliary value로 FUNC를 적용한다. VA는 entry의 가상 주소를 나타낸다. pte_for_each_func가 false를 반환하면, 반복을 멈추고 false를 반환한다.
아래는 pm14_for_each에 들어갈 func의 예시를 보여준다:
| |