페이지 폴트에는 3가지 종류가 있다.
1번과 2번의 경우 가상 메모리에는 찾고자하는 주소가 존재하나, 물리 메모리에는 존재하지 않는다.
이를 깃북에서는 bogus fault라고 한다.
지금까지는 위 2가지 경우도 page fault로 처리했지만,
이제는 위 경우가 발생하면 물리 메모리를 맵핑해서 페이지 폴트를 처리할 예정이다.
기존의 PintOS의 가상 메모리와 물리 메모리의 관계도
여기에 Supplemental page table 이라는 구조를 추가할 예정.
supplemental page table을 추가한 관계도
페이지 폴트 처리에 용이하게 페이지 테이블을 보완한 테이블.
비트맵, 리스트 등 여러 가지로 구현할 수 있지만 해시 테이블로 구현.
hash_init
으로 초기화.page_hash
, page_less
함수 만들기.page_hash
: page 구조체의 va
를 이용해 해싱 함수를 돌려 키를 만드는 함수page_less
: 페이지에서 원하는 값을 리스트에서 서치할 때 사용. 함수에는 va의 대소비교를 하는 내용이 들어 있음.spt
에 새로 할당한 페이지 테이블을 저장.pg_round_down
한 값을 page 구조체의 va
에 저장.va
를 이용해 해시 함수를 돌리고 그에 맞는 hash_elem
을 찾기 위한 장치로만 사용됨.pg_round_down(va)
을 실행하면 현재 va가 가리키고 있는 위치에서 offset만큼 내림. 리턴 값은 page 구조체의 시작점을 가리키게 된다.hash_find
로 spt
에서 인자로 받은 va
와 같은 키를 가지는 hash_elem
을 리턴한다.find_bucket
에서 아까 빈 page 구조체에 넣었던 va
를 이용해 해시 함수를 돌려 키를 찾고 그에 맞는 bucket 위치에 있는 리스트 반환page_hash
) 를 직접 호출하는 부분이 없다. h->hash
이 부분이 실제로 함수를 호출하는 부분이다. 구현 1에서 hash_init을 실행할 때 인자로 넣어준 함수들이 함수 포인터로서 page 구조체에 저장되어 있으므로 저런 식으로 함수 호출이 가능하다.find_elem
으로 find_bucket
이 반환해준 리스트에서 찾고자하는 va
를 가진 elem 탐색page_less
함수가 elem을 리스트에서 서치할 때 사용하는 비교 함수로써 사용됨.hash_entry
를 이용해 page 구조체를 받아와서 리턴hash_insert
로 해시 테이블에 page 를 삽입하고 그 결과를 true / false로 반환palloc_get_page
를 이용해 user pool에 페이지 할당PANIC(”todo”)
처리vm_get_frame()
으로 frame 동적 할당 및 user pool에 페이지 할당memory management에서 구현한 것은, 어떤 페이지 폴트인지는 잘 모르나, 페이지 폴트가 발생했을 때 그에 대한 처리로 프레임을 새로 할당하는 과정이었다.
진행 과정
- page fault 발생
spt
에서 page fault가 발생한 page 탐색 (spt_find_page()
)vm_get_frame()
으로 user pool에 페이지 할당vm_do_claim_page()
로 page, frame 연결- pml4에 페이지와 프레임 관계 맵핑(
pml4_set_page()
)
2부터 5까지의 과정은 모두 vm_claim_page()
함수를 한번 호출하면 진행되는 과정.
lazy loading이란?
메모리 로딩이 필요한 시점까지 오면 그제서야 물리 메모리에 맵핑을 하는 방식.
그 즉시 필요한 부분만 맵핑해서 메모리를 사용하므로 모든 메모리를 물리 메모리에 맵핑하는 Eager loading에 비해 오버헤드를 줄일 수 있다는 장점이 있다.
Anonymous Page란?
가상 메모리 공간에 페이지가 할당되어 있고 해당 페이지 구조가 있지만 전용 물리 프레임이 없고 실제 내용이 아직 로드되지 않은 페이지.
vm_try_handle_fault
로 유효한 페이지 폴트인지 확인하고 bogus fault인 경우 일부 내용을 페이지에 로드.load_segment
로 ELF 포맷 파일의 세그먼트를 디스크에서 가져와 가상 메모리에 적재. load_segment
내부의 vm_alloc_page_with_initializer
로 페이지 할당 및 초기화 vm_claim_page
로 물리 메모리 맵핑