크래프톤 정글 2기

[크래프톤 정글 2기] Day 75

KimCookieYa 2023. 6. 17. 11:32

회고

오늘은 깃북 순서를 따라 Supplemental Page Table의 본격적인 구현을 진행했다. 개념이 확립되지 않았지만, 어차피 깃북 내용과 Pint OS 코드 상의 구현은 또 달라서 직접 코드를 까보면서 이해하는 수 밖에 없다. 또 코드에 TODO로 구현해야 할 사항을 자세히 알려주기 때문에 코드를 구현하면서 이해하는 것이 효율이 좋다. 백 코치님이 말씀하시길, "Continuous improvement is better than delayed perpection". 완벽하게 시작하는 것보다 지속적으로 도전하는 것이 더 좋다. 직접 부딪혀봐야 알 수 있는 것이 있다.

Supplemental Page Table

보조 페이지 테이블

 

우선 struct supplemental_page_table에 해쉬 테이블 spt_hash를 멤버 변수로 추가했다. 이후 supplemental_page_table_init(), spt_find_page()와 spt_insert_page() 함수를 각각 구현했다. 페이지 테이블 pml4에서 특정 페이지를 찾을 수 없어서 page_fault()가 발생하면 해당 페이지를 SPT에서 찾아본다. SPT는 매핑되지 않은 가상 페이지를 관리하며 빠르게 물리 메모리와 매핑할 수 있도록 도와준다.

 

SPT의 개념에 대해서는 알겠지만, 기능을 직접 구현하는 것은 다른 이야기였다. SPT는 해시 테이블을 사용하여 구현하는 것이 좋은데 핀토스에서는 해시 테이블 라이브러리를 제공해준다. 근데 이거를 어떻게 사용해야 할 지를 모르겠다. 자료구조 사용하는 법부터 막힌다 ㅋㅋ. 동료들과 고민하다가 어떻게 해결했다.

 

해시 테이블은 해싱을 사용해서 저장할 데이터를 인덱스화한 후 데이터를 저장한다. 이 때 해싱에 필요한 함수를 구현해서 해시 테이을 초기화할 때 넣어주어야 한다. 우리가 구현한 함수 hash_func()는 다음과 같다. less_func()는 해시에 담긴 데이터 간 비교를 위한 함수인걸로 추정된다. 아직 미구현이다.

 

uint64_t
hash_func (const struct hash_elem *e, void *aux) {
    struct page* page = hash_entry (e, struct page, h_elem);
    return hash_bytes (page->va, 1 << 12);
}

bool
less_func (const struct hash_elem *a, const struct hash_elem *b, void *aux) {

}

 

Frame Management

보조 페이지 테이블을 구현한 후, 깃북에 따라 프레임 구현을 시작했다. 유저 가상 메모리의 가상 페이지와 매핑되는 물리 메모리의 영역이다. 프레임을 구현할 때부터 어려워졌는데, 프레임이 위치한 곳이 개념적으로는 물리 메모리이지만, 핀토스 상에서 구현할 때는 실제 물리 메모리를 사용할 수 없기 때문에 커널 가상 메모리 공간을 물리 메모리로서 사용하기 위해 커널 공간에 할당해주어야 한다. 이 차이를 알고 이해하는 것이 어려웠다.

 

깃북에 따라 vm_get_frame(), vm_claim_page(), vm_do_claim_lage()를 구현해주었다. vm_get_frame() 함수는 물리 메모리 공간을 할당받는 개념의 함수이다. 실제로 할당받는 곳은 유저 가상 메모리 공간의 커널 영역의 커널 풀이다. 여기서 어려웠던 것은 frame 구조체를 어떻게 할당시키는지와 프레임의 kva를 어떻게 할당시키는지 였다.

 

vm_get_frame (void) {
    struct frame *frame = NULL;
    /* TODO: Fill this function. */
    frame = (struct frame *)malloc (sizeof (struct frame));
    uint64_t *kva = palloc_get_page (PAL_USER);
    if (!kva) {
        free (frame);
        PANIC ("TODO");
    }
    frame->kva = kva;

    ASSERT (frame != NULL);
    ASSERT (frame->page == NULL);
Expand Down
Expand Up
    @@ -149,15 +176,26 @@ vm_dealloc_page (struct page *page) {
}