728x90
➡️ 과제 설명(Gitbook)
- 기존 스택의 크기는 4KB의 단일 페이지였다.
But, 이제는 스택이 현재 크기를 초과하면 필요에 따라 추가 페이지를 할당한다.
- 추가 페이지 : 스택에 접근하는 경우에만 할당
스택에 접근하는 경우와 아닌 경우를 구별하는 휴리스틱(경험적 접근방법)을 만들기
- 유저 프로그램은 스택 포인터 아래의 스택을 쓸 경우 버그가 발생한다.
- 일반적인 실제 OS가 스택 데이터를 수정하는 신호를 전달하기 위해 프로세스를 언제든지 방해(중단)할 수 있기 때문이다.
- 그러나 x86-64 PUSH 명령은 스택포인터를 조정하기 전에 접근 권한을 확인하기 때문에 스택포인터 보다 8bytes 아래에 page fault를 발생시킬 수 있다.
- 유저 프로그램의 스택 포인터의 현재 값을 얻을 수 있어야 한다.
- 시스템콜이나 유저 프로그램에 의해 발생한 page fault안에서 각각
syscall_handler
나page fault
에 전달된 구조intr_frame
의rsp
멤버에서 검색할 수 있다.- 시스템 콜은
syscall_handler
에 전달된 구조intr_frame
의rsp
멤버에 스택 포인터의 값을 확인 - page fault는
page fault
에 전달된 구조intr_frame
의rsp
멤버에 스택 포인터의 값을 확인
- 시스템 콜은
- 유효하지 않은 메모리 접근을 감지하기 위해 page fault를 의존(사용)하는 경우, 커널에서 발생하는page fault가 발생하는 다른 경우를 처리해야 한다.
- 예외로 인해 유저모드에서 커널모드로 전활될 때만 프로세서가 스택포인터를 저장하기 때문에
page_fault()
로 전달된struct intr_frame
에서rsp
를 읽으면 사용자 스택 포인터가 아닌 정의되지 않은 값을 얻을 수 있다. - 유저에서 커널 모드로 초기 전환시 rsp를
struct thread
에 저장하는 것과 같은 다른 방법을 준비해야 한다.
Implement stack growth functionalities
- 구현하기 위해서
vm_try_handle_fault(vm/vm.c)
를 수정하여 스택 증가를 확인 - 스택 증가를 확인한 후,
vm_stack_growth(vm/vm.c)
를 호출하여 스택을 증가시켜야 한다. - ⭐
vm_stack_growth
를 구현할 것!
bool vm_try_handle_fault (struct intr_frame *f, void *addr,
bool user, bool write, bool not_present);
- page fault 예외를 처리하는 동안
userprog/exception.c
에서page_fault()
로 호출된다. - 이 함수에서는 page fault가 스택을 증가시켜야 하는 경우에 해당하는지 여부를 확인해야 한다.
- 스택 증가로 page fault를 처리할 수 있다면, page fault가 발생한 주소로
vm_stack_growth
를 호출한다.
void vm_stack_growth (void *addr);
addr
이 더이상 page fault가 발생하는 주소가 되지 않도록 하나 이상의 익명 페이지를 할당하여 스택의 크기를 증가시킨다.- ⭐ 페이지를 할당할 때는 주소를
PGSIZE
기준으로 내림하기
- 대부분의 OS는 스택 크기가 절대적으로 제한되어 있다.
이번 프로젝트에서 스택의 크기를 최대 1MB로 제한해야 한다.
일부 OS는 사용자가 크기 제한을 조정할 수 있게 한다. GNU/리눅스 시스템에서 기본 제한은 8MB이다.
- 모든 stack-growth 테스트를 통과해야 한다.
728x90
'🌱 Dev Diary > 📄 TIL' 카테고리의 다른 글
Project 3. Memory Mapped Files (0) | 2023.01.19 |
---|---|
Project 3. Stack Growth(2) (0) | 2023.01.19 |
Project 3. Anonymous Page(2) (0) | 2023.01.19 |
Project 3. Anonymous Page(1) (0) | 2023.01.19 |
Project 3. Memory Management (0) | 2023.01.19 |