일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 핀토스 프로젝트 3
- 가테
- 핀토스 프로젝트
- 핀토스 프로젝트 2
- PINTOS
- 끝
- 바빠지나?
- 제발흰박
- 자 이제 시작이야
- 셋업
- 파란 장미
- 핀토스 프로젝트 1
- multi-oom
- 핀토스 프로젝트 4
- 일지 시작한 지 얼마나 됐다고
- 황금 장미
- alarm clock
- 노가다
- 마일섬
- 글리치
- 아직도 실험 중
- Project 1
- 글루민
- botw
- 내일부터
- Today
- Total
거북이의 쉼터
(2022.02.27) Anonymous Page 가이드라인 (1) 본문
저녁 먹고 돌아왔다. Anonymous Page의 매뉴얼을 읽어보자.
매뉴얼에 쓰여진 주된 사항은 anon.c의 코드를 수정하라는 것이다. VM_ANON 타입의 페이지는 이전 포스팅에서 언급한대로, 파일에서 기원하지 않은 모든 페이지, 즉 대다수의 페이지를 차지한다. 현재 실행되고 있는 프로세스의 내용, stack 등은 전부 VM_ANON 타입의 페이지로 메모리에서 관리된다.
그래서 구현해야 할 사항이 무엇인가 하고 봤다. 바로 Lazy Loading이 나온다. 지난 번에 언급했듯이 프로젝트 2까지 pintos는 전부 eager loading, 즉 페이지를 요청하자마자 페이지를 할당하여 내용을 채우고 반환하는 짓을 해왔다. 그러나 지금부터는 페이지를 요청한 뒤, 직접적으로 접근이 일어나기 전까지는 페이지를 할당하지 않도록 구현하라는 것이다. 이걸 위해 vm_alloc_page_with_initializer를 통해 우선 "임시 매핑"을 만들어 놓은 뒤 page fault가 일어날 때 실질적으로 할당과 매핑이 일어나도록 구성하도록 한다.
매뉴얼에서는 page fault를 valid와 bogus로 구분한다. valid는 정말 invalid한 주소에 접근하려고 해서 프로세스를 터뜨려야 하는 경우이며, bogus의 경우에는 몇 개의 작업을 통해 프로세스를 정상 궤도로 올려놓을 수 있는 경우이다. bogus의 경우 다시 3가지로 구분할 수 있는데,
- lazy-loaded 페이지에 접근
- swaped-out 페이지에 접근
- write-protected 페이지에 쓰기 권한 접근
3은 Copy-on-Write(Extra) 구현 전까지는 계속 valid page-fault일 것이니 일단은 1, 2에 집중할 것이다. 그리고 심지어 일단은 1에만 집중하란다.
우선 lazy loading을 위해 기본적으로 구현해야 하는 함수는 아래와 같다.
bool vm_alloc_page_with_initializer (enum vm_type type, void *va, bool writable, vm_initializer *init, void *aux);
static bool uninit_initialize (struct page *page, void *kva);
이 함수들은 앞선 포스팅에서도 설명했으니 넘어간다.
VM_ANON 타입의 lazy loading을 위해 구현할 부가적인 함수는
void vm_anon_init (void);
bool anon_initializer (struct page *page, enum vm_type type, void *kva);
위의 2개이다. 두 함수의 차이는 vm_anon_init의 경우 VM_ANON 타입의 페이지 전체를 위해 initialize 해야 하는 것들을 해 주는 함수이다. 예를 들어 swap 공간을 생성하고 초기화하는 것이 있다. 예라고 해 봤자 지금은 그거밖에 안보이지만.. anon_initializer는 주어진 페이지 자체에 대한 initialization인 것 같은데 uninit_initialize에서 해당 페이지에 대한 initialize를 진행할 때 불려야 하는 함수 같다. 일단 VM_UNINIT 타입의 페이지를 VM_ANON으로 바꿔주는 것만 진행하면 될 것 같다. swap in/out을 구현할 때 swapping에 필요한 추가 멤버가 있어서 이후에는 해당 멤버도 초기화시켜 주어야 할 것 같다. 일단 나중에 생각한다.
위에서 구현된 함수를 사용해서 프로젝트 3~4에 사용될 load_segment를 구현해야 한다. 프로젝트 2까지는 lazy load를 사용하지 않는 load_segment가 구현되어 있었고, load는 해당 함수를 사용했으나, 이제는 load_segment를 구현해야 한다. 구현할 함수들은 다음과 같으며,
static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable);
static bool lazy_load_segment (struct page *page, void *aux);
load_segment에서 일단 vm_alloc_page_with_initializer를 통해 VM_UNINIT 타입의 페이지를 생성해 놓은 뒤, 후에 page_fault로 initialize가 될 때 lazy_load_segment로 initialize를 하는 방식이다. argument passing이 이루어지는 첫 번째 stack page는 eager loading을 허용한다고 매뉴얼에 나오니 참고한다.
마지막으로 vm_try_handle_fault을 구현해서 page fault를 핸들링하도록 하면 우선 첫 번째 milestone에 도착한다. 여기까지 제대로 구현했다고 하면 fork를 제외한 나머지 프로젝트 2가 돌아가야 한다고 한다.
우선 여기까지 구현하는 것을 목적으로 하고 구현을 해 보자. 그래도 많아...
'코딩 삽질 > KAIST PINTOS (CS330)' 카테고리의 다른 글
(2022.03.05) Anonymous Page 구현 (1) (0) | 2022.03.05 |
---|---|
(2022.03.01) 급한 사정으로 pintos 잠시 중지 (0) | 2022.03.01 |
(2022.02.27) Memory Mgmt 구현 (0) | 2022.02.27 |
(2022.02.23) Memory Mgmt 가이드라인 (2/2) (0) | 2022.02.23 |
(2022.02.22) Memory Mgmt 가이드라인 (1/2) (0) | 2022.02.22 |