[WEEK 11] PintOS - Project 3: Virtual Memory (Demand Paging)

신호정 벨로그·2021년 10월 19일
0

Today I Learned

목록 보기
60/89

요구 페이징 구현

요구 페이징의 구현 순서는 5단계에 걸쳐 이뤄진다.

  1. page_fault(): 메모리 접근 및 페이지 폴트
  2. find_vme(): vm_entry 확인
  3. handle_mm_fault(): 메모리 할당
  4. load_file(): 디스크 -> 메모리 데이터 로드
  5. install_page(): 페이지 테이블 설정

1. 페이지 폴트 처리

PintOS는 페이지 폴트 발생시 처리를 위해 page_fault() 함수가 존재한다.

기존의 page_fault() 처리는 permission, 주소 유효성 검사 후 오류 발생시 무조건 "segmentation fault"를 발생시키고 kill(-1)하여 종료시킨다.

kill(-1)하여 종료시키는 명령을 삭제한다.

fault_addr()의 유효성을 검사하도록 수정한다.

페이지 폴트 핸들러 함수 handle_mm_fault()를 호출한다.

page_fault() 발생 주소 유효성 검사를 통해 유효한 주소이면 vm_entry를 검색한다.

handle_mm_fault() 핸들러를 통해 페이지를 할당하고 데이터를 파일로부터 메모리로 로드하고 페이지 테이블을 생성한다.

page_fault() 함수를 vm_entry를 검색한 후 페이지를 할당하도록 수정한다.

페이지 폴트 핸들러 구현

페이지 폴트 핸들러 handle_mm_fault()를 구현해야 한다.

handle_mm_fault()는 페이지 폴트 발생시 핸들링을 위해 호출되는 함수이다.

페이지 폴트 발생시 물리 페이지를 할당한다.

load_file()를 호출하여 디스크에 있는 파일을 물리 페이지로 적재한다.

install_page()를 호출하여 물리 메모리에 적재가 완료되면 가상주소와 물리주소를 페이지 테이블로 맵핑한다.

handle_mm_fault() 핸들러를 통해 페이지를 할당하고 vm_entry 타입을 확인한다.

VM_BIN 타입인 경우 파일로부터 메모리에 데이터를 로드하여 페이지 테이블을 셋업한다.

handle_mm_fault(): palloc_get_page()를 이용해서 물리 메모리를 할당한다.
switch문으로 vm_entry의 타입에 따라 처리한다. VM_BIN 바이너리 파일인 경우 load_file()을 호출하여 물리 메모리에 로드한다. install_page()를 이용해 물리 페이지와 가상 페이지를 맵핑한다. load의 성공 여부를 bool 자료형으로 반환한다.

3. 물리 메모리에 파일 쓰기

물리 메모리에 할당을 완료한 후 실제 디스크의 물리 페이지로 load한다.

load_file()은 디스크에 존재하는 페이지를 물리 메모리로 로드하는 함수이다.

vme의 파일과 오프셋으로 한 페이지를 kaddr로 읽어 들이는 함수를 구현해야 한다.

file_read_at() 함수 또는 file_read() + file_seek() 함수를 이용해 인자로 입력된 파일을 읽는다.

4KB를 전부 write하지 못했다면 나머지를 0으로 채운다.

vm_entry에 저장된 파일의 타입, 가상주소, read_bytes, zero_bytes, 오프셋, 파일 등 저장된 정보를 파일에 전달하여 디스크로부터 물리 메모리로 데이터를 로드한다.

load_file() 함수는 file_read() + file_seek() 함수를 이용한다.

file_seek() 함수를 이용해 오프셋을 vm_entry에 해당하는 오프셋으로 설정한다.

zero_bytes만큼 남는 부분을 0으로 채워서 패딩 처리한다.

file_read() 성공 여부를 반환한다.

  1. page_fault()로부터 기존의 kill(-1)을 통해 프로세스를 종료하는 부분을 수정한다.

handle_mm_fault()를 이용해 vm_entry를 검색한 후 페이지를 할당하도록 코드를 수정한다.

  1. load_file()는 디스크에 존재하는 페이지를 물리 메모리로 로드하는 함수이다.

vm_entry의 파일과 오프셋으로부터 한 페이지를 kaddr로 읽어 들이는 함수를 구현한다.

  1. handle_mm_fault() 핸들러가 페이지 폴트 발생시 물리 페이지를 할당하도록 구현한다.

페이지 주소 맵핑 함수

install_page()는 페이지 테이블에 물리주소와 가상주소를 맵핑하는 함수이다.

물리 페이지 kpage와 가상 페이지 upage를 맵핑한다.

인자 writable는 읽기만 가능한 경우 0을, 쓰기와 읽기가 모두 가능한 경우 1을 가진다.

PintOS의 페이지 테이블 구조

페이지 테이블과 페이지 디렉토리를 이용해서 물리 주소와 가상 주소의 맵핑을 관리한다.

  • 페이지 디렉토리: 페이지 테이블의 주소를 갖고 있는 테이블을 의미한다.

모든 가상 페이지에 대한 엔트리 사용은 비효율적이므로 한 단계 상위 개념인 페이지 디렉토리를 사용한다.

  • 페이지 테이블: 가상 주소에 맵핑된 물리 주소를 갖고 있는 엔트리들의 집합을 의미한다.

가상 메모리 주소에 포함된 인덱스로 엔트리에 접근한다.

struct thread 구조체의 멤버인 페이지 디렉토리를 통해 포함된 페이지 디렉토리를 찾는다.

페이지 디렉토리에 포함된 페이지 테이블을 찾아 가상 주소에 맵핑된 물리 주소를 갖고 있는 엔트리를 찾는다.

물리 페이지 할당 및 해제 인터페이스

  • palloc_get_page(): 4KB의 페이지를 할당하여 페이지의 물리 주소를 리턴한다.

인자 flags는 세 가지의 종류를 가진다. PAL_USER: 유저 메모리 풀에서 페이지 할당 / PAL_KERNEL: 커널 메모리 풀에서 페이지 할당 / PAL_ZERO: 페이지를 '0'으로 초기화

  • palloc_free_page(): 페이지의 물리주소를 인자로 입력하여 페이지를 다시 여유 메모리 풀에 넣는다.

0개의 댓글