왜 페이징이 필요한가?
Physical address에서 각 process의 공간이 꼭 연속적일 필요가 없게 해줌
virtual memory 공간을 page 단위로 나누고, physical memory 공간을 frame 단위로 나눈다. 보통 page는 4kB 많이 씀
연속성이 필수가 아니라서 External fragmentation이 완화된다 !!
어쨌든 이렇게 하려면 각 프로세스에서 Virtual address -> physical memory 맵핑이 필요함
이럴 때 사용되는 걸 Page Table이라고 하고, 만약 이를 악용하게 돼서 프로세스 A의 PT를 수정하여 프로세스 B의 메모리를 접근하게 하면 안되기 때문에 PT는 kernel만 수정이 가능하다 !!!!
PT는 physical memory에 있음 ( 당연함,,)
요론식으로 page크기가 4kB다! 이러면 physical memory에서도 사이즈를 4kB로 보통 사용하기 때문에 이때 Offset은 수정할 필요가 없음
그래서 페이지 사이즈인 4KB, 즉 12칸을 offset으로 사용하고 앞의 20칸을 Virtual Page Number로 사용한다. 20bit의 VPN을 적절히 Page Frame Number에 맵핑해서 VM -> Physical로 잘 찾아갈 수 있도록 해줘야함 !
이런 구성으로 생각해보고 PTE가 4B라고 하면, 우리는 VPN이 2^20개 있다는 걸 알 수 있다. 따라서 Page Table이 2^20 * 4B = 4MB의 공간을 필요로 하는데, 이는 엄청난 낭비(!!)임을 알 수 있다.
위에서 언급했듯이 서로 다른 Process가 서로의 메모리를 함부로 침범하면 안되기 때문에 page table은 process마다 분리해서 사용한다. context switch시, MMU register가 각 프로세스의 page table의 base address를 가리키도록 세팅된다.
각각의 Page를 접근하기 전에 Valid/ Invalid bit을 확인한다.
Invalid인 경우, page가 할당되지 않은 것!
PTE는 다음과 같이 구성되어 있는데,
V
V같은 경우는 Valid bit인지.
언제 invalid냐? 바로 evict 당한 page를 참조할 때 !
R(Reference)
page가 참조가 되어 있는지
M(Modify)
해당 page에 write이 발생했는지 (얘는 disk로 보낼 때 수정해줌)
R & M은 결국 memory에서 disk로 보낼 후보군을 추릴 때 사용됨
OS는 main memory를 일종의 cache처럼 사용하는 것임
(디스크에서 가져오기엔 느리니까)
그래서 필요할 때만 page를 가져오는 것
page는 걔네의 physical memory frame으로부터 쫓겨날 수도 있다. 따라서 이때 PTE를 invalid로 해야 쫓겨나고 바뀐 PF을 접근하지 않을 수 있겠지 !!
필요할 때만 올리니까 당연하 I/O나 memory를 조금 덜 쓰고 response가 빨라짐 (10page짜리 프로그램을 돌릴 때 10page다 올려놓고나서 시작하는게 아니라 우선 당장 필요한 1page를 올려놓고 그걸 실행하면서 나머지도 필요할 때 올릴 수 있음)
더 많은 process를 실행할 수 있다.
CPU가 PTE에 접근하고자할 때 invalid PTE를 만나면 exception을 던진다.
보통은, page 자체는 valid한데 memory에 load가 되어 있지 않아서 fault가 발생한다.
이때 !! => disk I/O를 요구하여 disk에서 page를 가져온다.
Invalid한 경우는 Segmentaion violation, 즉 해당 page가 사용되고 있지 않은 경우 (disk로 쫓겨난 경우)
이떄 page table역시도 physical memory에 있기 때문에 한 번의 추가적인 memory access가 필요해짐
저번 시간까지 배웠던 trap handler의 경우, exception이 발생하면 보통은 다음 instruction으로 가는데 얘는 다시 동일한 instruction으로 가서 재 실행 !