[PintOS] Project 3 : VM - MMAP/MUNMAP - 개념 정리

CorinBeom·2025년 6월 5일

PintOS

목록 보기
14/19
post-thumbnail

📌 mmap & munmap

Stack Growth에서 익명 페이지를 다뤘다면, 이제는 한 단계 진화한 파일 기반 가상 메모리다.
바로 mmap()munmap()이 그 주인공이다.


✅ mmap이란?

메모리에 파일을 맵핑한다(Memory Mapping a File)
즉, 유저 프로그램이 특정 주소에 접근하면, 마치 메모리처럼 동작하지만 실제로는 파일 데이터를 읽는 것이다.

  • 유저가 mmap()을 호출하면,
  • 운영체제는 파일 내용을 페이지 단위로 나누고,
  • 해당 주소에 파일 내용을 읽어오는 페이지들을 등록한다.
  • 그리고 page fault가 날 때만 진짜로 파일을 읽는다.

→ 이게 바로 Lazy Loading이다.


✅ munmap이란?

맵핑을 해제한다(Unmap)
더 이상 파일 데이터를 메모리처럼 접근하지 않도록 한다.
그리고 중요한 게 하나 있다:

  • 페이지가 수정되었으면 → 파일에 반영(write-back) 해야 한다.

🧠 mmap을 왜 쓰는가?

  • 파일을 한 번에 메모리에 로딩하면 낭비가 심함
  • 그래서 필요한 시점에만 로딩하는 Lazy 방식
  • 파일에 직접 쓰는 게 아니라, 메모리를 수정하고 나중에 write-back
  • 마치 파일과 메모리를 연결한 가상 인터페이스

✅ mmap 동작 흐름 요약

  1. mmap() 호출 시:

    • 주소, 파일 포인터, 오프셋, 길이 등을 받아서
    • 해당 범위를 페이지 단위로 쪼갠다
    • 각 페이지마다 어디서부터 읽을지, 얼마나 채울지 계산
    • vm_alloc_page_with_initializer()를 통해 페이지를 등록
    • 이때 핸들러로 lazy_load_segment()를 설정 → 진짜 로딩은 안 함
    • 첫 페이지에 전체 페이지 수(mapped_page_count) 를 저장해둔다
  2. 유저가 해당 주소에 접근하면:

    • Page Fault 발생
    • 등록해둔 lazy_load_segment()가 호출됨
    • → 파일을 읽어와 물리 페이지에 적재
    • → 이제 정상적으로 읽기/쓰기 가능

✅ munmap 동작 흐름 요약

  1. 유저가 munmap(addr) 호출 시:
    • 해당 주소 기준으로 mapped_page_count만큼 순회
    • 각 페이지가 dirty(수정됨) 상태인지 확인
    • dirty면 → 파일에 write-back (ex: file_write_at)
    • 이후 페이지를 제거(destroy)

✅ Dirty Page란?

  • 유저가 파일을 메모리처럼 쓰게 되면, 해당 페이지는 수정됨
  • 그런데 즉시 파일에 반영하지는 않음 → 효율성 때문
  • 대신, 페이지 테이블의 dirty bit로 변경 여부를 추적
  • unmap 시 이 dirty 비트를 확인해서 진짜 변경된 경우만 저장

✅ mmap/munmap을 통해 배우는 운영체제 개념

개념설명
Lazy Loading실제 접근 시점까지 메모리를 로딩하지 않음
File-backed Page파일을 backing store로 사용하는 가상 페이지
Dirty Bit 활용페이지의 수정 여부를 추적해 write-back 수행
Write-back메모리 수정 내용을 파일에 되돌려 쓰기
Page Table 활용페이지의 상태와 종류를 kernel이 추적
Resource 관리unmap 시점에 자원을 정확히 회수해야 함

✅ 흐름 정리 (텍스트로만 보는 마인드맵)

mmap()

  • 유저 → mmap 호출
  • 커널
    • 페이지 단위로 나누기
    • read/zero bytes 계산
    • 각 페이지를 lazy 방식으로 등록
    • 파일 offset 정보도 저장
  • 유저가 페이지에 접근 → Page Fault 발생
    • lazy_load_segment() 호출
    • 실제로 파일에서 읽어서 적재

munmap()

  • 유저 → munmap 호출
  • 커널
    • 해당 영역의 페이지들을 하나씩 확인
    • dirty면 파일에 write-back
    • 페이지 제거 및 메모리 반납
do_mmap()
├─> for each page:
│    ├─ calculate read/zero bytes
│    ├─ set up load_info
│    └─ vm_alloc_page_with_initializer(VM_FILE, ...)
│
└─> 첫 페이지에 mapped_page_count 저장

→ 유저 접근 → page fault → lazy_load_segment → file_read_at

do_munmap()
├─> for count = mapped_page_count
│    ├─ check dirty bit
│    ├─ if dirty → file_write_at()
│    └─ destroy(page)

mmap/munmap 구현을 위해 필요한 것들

범주내용
시스템 콜 구현sys_mmap(), sys_munmap()
핵심 로직 함수do_mmap(), do_munmap()
lazy handler 함수lazy_load_segment()
file-backed 핸들러 함수들file_backed_initializer(), file_backed_swap_in(), file_backed_swap_out(), file_backed_destroy()
파일 정보 보관 구조체struct load_info
추적을 위한 필드page->mapped_page_count, file_page->file, ofs, read_bytes, zero_bytes
dirty 체크 및 write-backpml4_is_dirty(), file_write_at(), pml4_set_dirty()

✅ 마무리

mmap과 munmap은 "파일을 메모리처럼" 다루게 해주는 마법 같은 인터페이스다.
이는 단순한 기능이 아니라 운영체제가 메모리와 저장소를 연결하는 방식을 보여주는 정수이기도 하다.

Stack Growth가 가상 메모리의 시작이었다면,
mmap은 그 확장판이자 실제 운영체제에서 공간 절약과 성능 향상을 동시에 실현하는 중요한 기술이다.

다음 포스팅에서는 구현해야 할 함수들에 대해 더 자세하게 알아보자

profile
Before Sunrise

0개의 댓글