기존의 핀토스 운영체제는 가상주소 공간 초기화 과정에서는 ELF 이미지의 각 페이지를 물리 메모리로 읽어들인다.
load_segment() 함수를 통해 데이터와 코드 세그먼트를 읽고 setup_stack() 함수를 통해 스택에 물리 페이지를 할당한다.
디스크 이미지의 세그먼트를 전부 올리는 것은 물리 메모리의 낭비를 초래하기 때문에 수정된 핀토스의 가상 주소 공간을 초기화하는 과정에서는 물리 메모리를 할당하는 대신, 가상 페이지마다 vm_entry를 통해 적재할 정보들만 관리한다.
기존의 핀토스는 프로그램의 모든 세그먼트에 대해 물리 페이지를 할당한다.
요구 페이징은 프로세스가 요청한 페이지들에 대해서만 물리 페이지를 할당해주는 기법이다.
요구 페이징을 위해 요청한 페이지에 대해서만 물리 페이지 할당을 수행한다.
load_segment() 함수는 ELF 포맷 파일의 세그먼트를 프로세스 가상주소 공간에 탑재한다.
기존의 load_segment() 함수에 프로세스 가상 메모리 관련 자료 구조를 초기화하는 기능을 추가한다.
프로세스 가상주소 공간에 메모리를 탑재하는 부분을 제거하고, vm_entry 구조체의 할당, 필드값 초기화, 해시 테이블 삽입을 추가한다.
스택을 초기화하는 기존의 setup_stack() 함수는 단일 페이지를 할당하고 페이지 테이블을 설정하고 스택 포인터(esp)를 설정한다.
setup_stack() 함수가 4kb 크기의 스택의 vm_entry를 생성하고, 생성한 vm_entry의 필드값을 초기화하고 vm 해시 테이블에 삽입하도록 수정한다.
주소 유효성 검사란 가상주소에 해당하는 vm_entry가 존재하는지 검사하는 것이다.
시스템 콜(read/write)을 사용할 시 인자로 주어지는 문자열이나 buffer의 주소에 해당하는 vm_entry가 존재하는지 검사한다.
buffer의 시작주소에 해당하는 vm_entry의 존재여부를 검사한다.
기존의 check_address() 함수는 스택 포인터 esp에 대한 유저 메모리 영역을 체크한다.
vm_entry를 사용하여 유효성 검사 작업을 수행하고 vm_entry를 반환하도록 수정한다.
buffer를 사용하는 read() 시스템 콜의 경우 buffer의 주소가 유효한 가상주소인지 검사해야한다.
buffer의 유효성을 검사하는 함수인 check_valid_buffer() 함수를 추가한다.
check_valid_buffer() 함수는 buffer에 내용을 쓸 수 있는지 검사하는 to_write() 변수를 포함한다.
시스템 콜에서 사용할 인자의 문자열의 주소값이 유효한 가상주소인지 검사하는 check_valid_string() 함수를 추가한다.
check_valid_buffer() 함수는 인자로 입력하는 buffer부터 buffer + size 까지의 크기가 한 페이지의 크기를 넘을 수도 있기 때문에 check_address() 함수를 통해 주소의 유저 영역 여부를 검사하고 vm_entry 구조체를 받는다.
해당 주소에 대한 vm_entry 존재 여부와 vm_entry의 writable 멤버가 true인지 검사한다.
buffer부터 buffer + size까지의 주소에 포함되는 vm_entry들에 대해 적용한다.
함수 내 check_address() 함수의 인자값을 변경하도록 syscall_handler() 함수가 수정한다.
시스템 콜 호출 시 인자값의 유효성 검사를 하도록 수정한다.
buffer 사용 유무를 고려하여 유효성 검사를 하도록 수정한다. (read/write 시스템 콜)