Project3: Virtual Memory - Memory Mapped Files

김민호·2025년 12월 6일

pintos

목록 보기
9/9

1. Memory Mapped Files 개념

지금까지는 파일 입출력(read, write)을 수행할 때 버퍼를 이용하는 방식을 사용해왔다. mmap은 파일을 프로세스의 가상 메모리 주소 공간에 직접 매핑하여, 마치 메모리를 다루듯이 파일을 다룰 수 있게 해주는 기능이다.

이제 파일 데이터를 페이지 단위로 관리하며 가상 메모리 시스템과 통합해야 한다.


2. mmap 구현 (do_mmap)

시스템 콜 mmap은 실제 로직을 수행하는 do_mmap을 호출하는 래퍼(Wrapper) 형태로 구성된다. 핵심은 매핑 요청이 유효한지 검증하는 과정이다.

유효성 검사 루틴

addr(매핑 시작 주소)에 대해 다음 조건들을 순차적으로 확인해야 한다. 실패 시 NULL을 반환한다.

  1. 기본 주소 검사: addr이 NULL이거나 0이 아니어야 한다.
  2. 페이지 정렬: 주소가 정확히 4KB 단위로 나누어 떨어져야 한다. (pg_ofs(addr) == 0)
  3. 영역 중복 검사 (spt_find_page):
    • 이미 실행 중인 코드/데이터 영역과 겹치지 않아야 한다.
    • 스택 영역과 겹치지 않아야 한다.
    • 이전에 mmap으로 할당된 다른 영역과 겹치지 않아야 한다.
  4. 영역 범위 검사 (is_user_vaddr): 매핑하려는 주소 공간이 커널 영역이 아닌 사용자 영역 내에 존재해야 한다.

페이지 할당

검증이 완료되면 vm_alloc_page_with_initializer()를 사용하여 페이지를 할당한다. 이때 페이지 타입은 VM_FILE이 된다.


3. munmap 구현 (do_munmap)

munmap은 addr부터 시작하여 연속된 VM_FILE 페이지들을 해제하는 과정이다.

연속된 페이지 처리 문제

단순히 addr만 주어졌을 때, 몇 개의 페이지를 해제해야 하는지 알 수 없는 문제가 있다.
이를 해결하기 위해 매핑된 첫 번째 페이지의 구조체에 할당된 총 페이지 개수 정보를 저장해 두어야 한다.

do_munmap 호출 시, 첫 페이지에서 페이지 개수를 확인하고 정확히 그 횟수만큼 루프를 돌며 해제 작업을 수행한다.


4. 데이터 동기화 (Dirty Bit & Write Back)

메모리에 매핑된 파일 데이터가 수정되었다면, 언젠가는 디스크의 실제 파일에도 반영해줘야 한다.

동기화 시점의 결정

Dirty Bit(수정 여부)를 확인하고 파일에 쓰는 작업을 어디서 수행해야 할까?
1. munmap 시점: 사용자가 명시적으로 해제를 요청할 때 수행된다.
2. file_backed_destroy 시점: 페이지가 파괴될 때 수행된다.

정답은 file_backed_destroy 내부에서 처리하는 것이다. 프로세스가 정상 종료(process_exit)되거나 강제 종료될 때도 SPT가 정리되면서 destroy 함수가 호출되기 때문이다. 이곳에서 처리해야 모든 상황(명시적 해제 및 프로세스 종료)을 커버할 수 있다.


5. 구조체 수정 및 데이터 흐름

파일에 변경 사항을 쓰기 위해서는 해당 페이지가 '어떤 파일'의 '어느 오프셋'에 연결되어 있는지 알아야 한다.

구조체 설계

struct page 내부의 union에 정의된 file_page 구조체에 aux 정보가 필요하다.
이 aux 필드에는 파일 객체(struct file *)와 읽은 바이트 수, 오프셋 등의 정보가 담겨야 한다.

정보 전달 흐름

페이지가 처음 생성될 때는 VM_UNINIT 상태이다. 이때 lazy_load_info 등을 통해 파일 정보를 가지고 있다.
페이지 폴트가 발생하여 file_backed_initialize가 호출될 때, uninit_page가 가지고 있던 aux 정보를 file_page의 aux로 이관해 주어야 한다.


6. 동기화 구현 요약

  1. 구조체 확장: file_page 구조체에 파일 정보(aux)를 저장할 필드를 추가한다.
  2. 초기화 로직: file_backed_initialize 함수에서 uninit 상태의 aux 데이터를 file_page로 복사/이동시킨다.
  3. 파괴 로직: file_backed_destroy 함수 구현 시, pml4_is_dirty를 통해 수정 여부를 확인한다. 수정되었다면 file_write_at 등을 사용하여 디스크에 내용을 기록하고 페이지를 해제한다.
profile
개발자를 꿈꾸고 있어요

0개의 댓글