https://gyumingomin.tistory.com/92
Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도]
https://gyumingomin.tistory.com/91 Pintos - SPT(Supplemental Page Table)와 Hash TableSPT(Supplemental Page Table)에서 hash table을 왜 쓸까?Pintos VM에서 핵심page fault가 발생했을 때, 이 가상주소에 대한 정보를 빠르게 찾아야
gyumingomin.tistory.com
위 과정을 따라가면, page_fault까지의 흐름을 이해할 수 있을 것 같은데? 이해가 안가는 부분이 생기면 질문 부탁드립니다!! (for update)
1. vm_try_handle_fault
bool vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED, bool user UNUSED, bool write UNUSED, bool not_present UNUSED);
1-ⓐ. 현재 PF난 주소가 실제로 존재하거나 유저가상주소가 맞는지 확인하고 핀토스에서는 page는 있는데 권한 위반일 경우 실패처리를 한다.
1-ⓑ. 유저 가상 주소의 시작점을 찾고, spt에 페이지가 존재하는지를 체크한다.
1-ⓒ. 페이지가 spt에 존재하지 않으면 stack growth [여기서 중요한 점 - 알아가야할 개념]
⑴. code, data, stack, mmap의 차이 - 아래는 메모리 영역과 예시코드

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
int global_var = 10;
char global_str[] = "Hello";
int main() {
int local_var = 20;
int fd = open("data.txt", O_RDONLY);
char *mapped = mmap(NULL, 4096,
PROT_READ,
MAP_PRIVATE,
fd, 0);
printf("%d\n", global_var);
printf("%d\n", local_var);
printf("%s\n", mapped);
return 0;
}
이 프로그램 안에서 code, data, stack, mmap이 각각 어떻게 동작하는지 알아보고자 한다.
1. Code 영역 (Text Segment)
"실행 명령어"가 들어있는 영역
printf("%d\n", global_var); 이 코드가 C 컴파일 되면 아래와 같은 기계어로 바뀌는데, 이 기계어 자체가 code 영역에 들어감
mov ...
call printf
즉, main 함수 호출 printf 호출, open 호출 코드 같은 "CPU 실행할 명령어"가 들어있는 곳
특징
보통 읽기 전용
실행 가능 (Executable)
프로그램 시작 시 ELF에서 로드 됨
2. Data 영역
전역변수 / static 변수가 들어있는 영역
int global_var = 10; char global_str[] = "Hello" 처럼 이 두개는 함수 밖에 있으므로 data 영역에 저장
특징
함수 끝나도 안 사라짐
프로그램 종료까지 유지
read/write 가능
3. Stack 영역
함수 호출 시 생기는 임시 공간
int local_var = 20; 이건 main 함수 안의 지역변수라 stack에 들어감
특징
함수 호출 시 생성
함수 종료 시 제거
(스택처럼 함수안에 함수의 지역변수가 쌓이면서 함수가 끝나면 FILO로 빠져나감)
아래 방향으로 성장 (메모리 영역에서 주소가 할당되는 방식)
4. mmap 영역
mmap()은 파일 내용을 메모리에 "매핑" 하는 것
char *mapped = mmap(...); 이걸 하면 data.txt 파일-> 가상 메모리 주소와 연결
그래서 실제로 mapped[0]에 접근 시 실제로는 "RAM에 파일 내용을 page 단위로 올리는 구조"
정리 (핵심 차이)
프로그램 실행 시 ELF 로더가 자동으로 올림 (code / data)
실행 도중 프로그램이 직접 요청 (mmap) 하는 순간 새 가상 메모리 생성
-> SPT에 프로그램이 올라갔을 때 초기화 단계부터 정상적으로 페이지는 생성됨
-> SPT에 stack은 함수가 호출 되면서 메모리에 적재되는 방식이므로 초기화 단계에 페이지가 없을수도 있음
따라서 spt에 페이지가 존재하지 않을 때, stack growth 가능한지 여부를 체크하는 이유는 (stack은 페이지가 초기에 할당되지 않고 새로 생겨날 수 있기 때문이다. (다른 조건 code, data, mmap 같은 경우는 초기에 프로그램이 로더될 때 바로 spt에 페이지가 할당된다.)
⑵. stack growth 조건 검증 이유
예를 들어,
void foo() {
int a = 10;
int b = 20;
}
foo()가 호출되기 전에는 a, b를 위한 스택 공간은 존재하지 않는다.
함수 호출 순간 main() -> foo() 호출
CPU가 아래 작업을 하면서 rsp를 아래로 내린다.
1. return address 저장
2. 이전 rbp 저장
3. 지역변수 공간 확보
호출 전
rsp -> 0x800000
foo 진입 후
rsp -> 0x7ffff0
이렇게 스택이 성장한 후 ( 그 공간 안에 )
[a] [ox7ffff8]
[b] [ox7ffff6]
return address [ox7ffff4]
saved rbp [ox7ffff2]
그리고 함수가 끝나면 return 하면서
mov rsp, rbp
pop rbp
ret
등이 실행되어 스택 포인터가 원래 위치로 돌아간다.
따라서 fault가 난 addr가 "현재 스택 포인터 rsp 근처인지"를 확인하고
USER_STACK영역 안인지 확인하고
[핀토스 내부에서의 정책] STACK크기가 최대 1MB까지만 자라게 제한을 둠
1-ⓓ. page가 spt에 존재하지 않아 stack 확장중인지 체크했는데도 페이지가 할당되지 않았다거나 CPU가 보기에 이번 page fault는 쓰기(write) 때문에 발생했는데, Pintos가 SPT에 저장해 둔 해당 page 정보는 "이 페이지는 쓰면 안된다" 이러면 잘못된 접근이므로 실패 처리
1-ⓔ. vm_do_claim_page
static bool vm_do_claim_page (struct page *page);
이 내용은 추가로 다른 페이지에서 구현 예정
'정글캠프-WIL > 핀토스' 카테고리의 다른 글
| pintos - vm_do_claim_page 구현 (0) | 2026.05.16 |
|---|---|
| Pintos - interrupt 비교 (#PF(page fault), Timer Interrupt) (0) | 2026.05.15 |
| Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도] (0) | 2026.05.14 |
| Pintos - SPT(Supplemental Page Table)와 Hash Table (1) | 2026.05.12 |
| Pintos - VM [vm.h 학습] (0) | 2026.05.11 |
