이 포스트는 널널한 개발자님의 강의를 듣고 작성한 글입니다.
페이징 기법은 매우 중요하다. 이게 왜 중요하냐면 C언어와 같은 native code를 공부할 때 제일 힘든 부분이 포인터이다. 근데 포인터를 다들 이해하고 나면 자유를 얻는다. 즉, 이것이 절대적 권력이라는 것을 느낄 수 있다. 그러면 왜 어려워들 할까? 그 이유는 컴퓨터 구조에 대한 이해가 낮아서 그럴 수도 있고 기본적으로 VMS에 대한 개념이 없기 때문이다.
일단 우리가 대전제로 알아야 할 것이 VMS를 32bit 기준으로 이해하면 한마디로 4GB 배열이다. 쉽게 말해서 char[42.9억];
인 배열이다. VMS 자체는 논리적으로 봤을 때 완벽하게 선형 메모리이다. 즉 char[42.9억]
에 우리가 알고 있던 stack도 있는거고 heap도 있는거고 그 외에 정적영역등 모든 것이 이 배열에 들어가져 있다.
가상주소가 있고 물리주소가 있는데 한마디로 물리주소는 RAM을 말하는거고 VMS는 프로세스마다 갖는다. 프로세스가 n개가 존재한자면 모두가 각자 100번지 주소를 갖는다고 가정한다면 이 100번지가 실제 RAM의 똑같은 100번지일까? 전에 애기했듯이 아니다.
페이지란 별거없고 32bit체계 메모리가 있다고 했을때 0번지부터 0xFFFFFFFF까지 존재할 것이고 중간에 4095번지에서 끊었을 때 여기까지 용량이 4KB정도 될것이다. 그런데 페이지라는 것이 윈도우 기준으로 4KB씩 끊는다. 그리고 RAM 메모리가 페이지단위 혹은 세그먼트 단위로 끊을 수 있는데 어쨌든 페이징이든 세그먼테이션이든 일정 단위로 끊는것을 프레임이라 보자.
가상주소의 페이지 1개가 4KB면 실제 메모리도 4KB씩 맞추는데 그 각각에 대한 프레임 사이즈를 매핑한다.
핵심적인것은 하나의 block처럼 일정단위로 잘랐다는 것이고 이렇게 잘라가지고 단위화했다는 것이다. 우리가 C언어에서 2차원 배열을 배우는데 이거랑 비슷한 개념이다. 만약 VMS가 특정 아파트 단지라고 했을 때 페이지는 동이 되는거고 그리고 호는 페이지에서 일정 구간 떨어진 메모리 주소가 될 수 있다. 그럼 여기서 중요한게 어떤 기준(절대적)이 있는거고 그 기준으로부터 얼마만큼 떨어진 주소를 상대주소라고 말하게 된다. 이 상대적 위치를 영어로 distance 혹은 offset이라고 한다. 그래서 메모리상 주소가 있는데 예를 들어 page 1번으로 따라가면 페이징 테이블에 실제 메모리 주소와 연결시켜준다.
좀 더 자세히 보면 VA = <페이지 번호, distance>로 표기하는데 이걸 페이지 테이블에 매핑된 부분을 따라가서 실제 물리주소로 가는거고 거기에 특정 거리만큼 떨어진 메모리 주소에 I/O하는 과정이다.
서두에 C언어 공부하면서 포인터 어려원한다는 애기를 꺼낸 이유는 페이지 테이블에 가끔 invalid라는 부분이 있는데 이 부분과 연결된 실제 메모리 주소는 없다는 의미이다. 예를 들어 아래와 같은 코드를 짰다 해보자.
*pszResult
는 주소값이 들어가져 있는데 이 주소를 따라가서 페이지 테이블이 만약 invalid라고 하면 결과는 page Fault라는 에러메세지가 나오게 된다. 만약 물리 메모리를 세그먼테이션으로 관리한다면 Segmantaion fault라고 나올 것이다.