현재 핀토스에서는 **레벨 4 페이지 테이블(pml4
)**을 사용하여 가상 메모리 주소와 물리 메모리 주소 간의 매핑 정보를 저장한다. 하지만 이것만으로는 충분하지 않다. 따라서 Page Fault와 Resource Management를 수월하게 진행할 수 있도록 Supplemental Page Table을 구현해 페이지에 대한 추가적인 정보들을 저장한다.
Supplemental Page Table
supplemental page table은 기존의 page table을 보완하기 위해 만든 것이다.
역할
크게 두 가지 역할을 수행한다.
- 페이지 폴트 시 커널이 추가 페이지 테이블에서 오류가 발생한 가상 페이지를 조회하여 어떤 데이터가 있어야 하는지 확인
- 프로세스가 종료될 때 커널이 추가 페이지 테이블을 참조하여 어떤 리소스를 free시킬 것인지 결정
추가 페이지 테이블을 만든 이유(출처)
- 여러 page-table entry가 같은 하나의 physical address를 가리키고 있지만, 다른 page-table entry도 같은 physical address를 가르킬 수 있다. 왜냐햐면 page-table은 page-directory-entry마다 하나씩 가지고 있고, 서로 다른 virtual address를 가지지만 같은 physical memory를 참조하는 경우가 충분히 발생할 수 있기 때문이다. referencing하고 있는 table들은 전부 다르지만, 결국 같은 physical address를 가르키고 있는 것이다. 이러한 경우를 다루기 위해서는 하나의 프로세스가 어떠한 physical memory를 참조하고 있는지에 대한 정보가 필요하고, 이를 위해서 추가적인 page table이 필요한 것이다.
- 기존의 page-table은 physical memory를 향한 일방적인 pointing에 불과하다. 때문에 physical-memory의 값이 바뀌어 있으면 패닉에 빠질 수 밖에 없다. 기존에 어떠한 데이터가 있는지에 대한 정보를 전혀 가지고 있지 않기 때문에 이러한 문제가 발생하면 해결할 수가 없다. 따라서 supplementary page table에는 원래 physical-memory에 들어가 있어야 할 데이터가 어떤 것인지에 대한 정보를 가지고 있어야 한다.
- resource-free를 할 때에 어떠한 데이터를 FREE할지를 결정하는데에 사용된다. 두 번째 이유에서 설명한 것을 바탕으로 충분히 직관적인 이해를 할 수 있으리라 본다.
struct supplemental_page_table 구현
먼저 추가 페이지 테이블의 구조체 struct supplemental_page_table
을 구현한다. 그 후에 추가 테이블 구조체에 관계된 함수를 구현한다.
Supplemental page table을 구현하는 방식은 여러 가지가 있을 수 있다. 배열이나, 비트맵, 해시 테이블도 가능하다. 우리는 **hash table로 구현하기로 한다.**
hash table이란?
lib/kernel/hash.h/struct hash
/* Hash table. */
struct hash {
size_t elem_cnt; /* Number of elements in table. */
size_t bucket_cnt; /* Number of buckets, a power of 2. */
struct list *buckets; /* Array of `bucket_cnt' lists. */
hash_hash_func *hash; /* Hash function. */
hash_less_func *less; /* Comparison function. */
void *aux; /* Auxiliary data for `hash' and `less'. */
}
struct page 수정