#
# 이 파일은 Gonio에 구현된 페이징의 이론적인 부분입니다.
# 작성자 : Hygon
#

목차

1. 페이징이란
2. 페이징을 하기 위해 필요한 것
3. 각각 구성요소에 관한 내용
3-1. 페이지 디렉터리
3-2. 페이지 테이블
3-3. 페이지 엔트리


1. 페이징이란

페이징(Paging)이란 운영체제가 메모리를 관리하는 방법 중 하나로
가상 주소(Virtual Address 혹은 Logical Address)를 통해 메모리를
접근하는 방법입니다.

페이징을 하게되면 주소가 가상 주소와 물리 주소로 구분되고 
가상 주소를 통해서만 접근을 하게 되는데

먼저 물리주소란 페이징을 적용하기 전에 접근하는 형태의 주소가 물리 주소이고

가상 주소란 말 그대로 가상 주소인데 개념적인 주소로, 32비트 에서는
물리적인 램이 부족하더라도 4GB 범위의 주소를 사용할 수 있습니다.

단, 4GB 범위의 '주소' 만 사용 가능한것이지 4GB 범위의 '공간'은 물리적인
메모리가 없다면 사용이 불가능합니다.

또한, 가상 주소를 통해 메모리에 접근을 하려면 가상 주소를 물리 주소로
변환해주는 자료구조가 필요한데, Gonio 에서는 3단계 페이징을 사용하므로

페이지 디렉터리, 페이지 테이블, 페이지 엔트리를 통해 가상 주소를
물리 주소로 변환하게 됩니다.

가상 주소를 물리 주소로 변환하는 작업은 프로세서의 MMU(Memory Management Unit) 이 담당하지만 
위에서 말한 자료구조는 우리가 만들어야 합니다.


먼저 가상 주소는 GDT 테이블을 참고해서 만들어진 선형 주소를 기준으로 보고,
이를 세 부분으로 분리합니다.

[페이지 디렉터리 인덱스][페이지 테이블 인덱스][페이지 엔트리 오프셋]
페이지 디렉터리/테이블 인덱스는 각각 10 비트이고, 2^10 까지
표현이 가능하므로 페이지 디렉터리와 페이지 테이블은 1024개의 엔트리를
가질 수 있습니다. 그리고 나머지 12비트는 페이지 엔트리 인덱스 이고
2^12 = 4KB 이므로 한 페이지에서의 모든 오프셋에 접근할 수 있습니다.

또한 가상 주소를 물리 주소로 변환할 땐,
먼저 페이지 디렉터리에서의 인덱스를 보고, 만약 인덱스가 3이라면
(0에서 시작하므로) 4 번째 엔트리에 접근합니다.

페이지 디렉터리의 엔트리는 페이지 테이블의 주소와 속성을 가지고있고
주소를 참고하여 페이지 테이블의 주소로 갑니다.

그러고 나서는 페이지 테이블 인덱스로 여기서는 2라고 가정을 하면
3 번째 엔트리로 가게됩니다.

3 번째 엔트리에는 페이지의 주소가 있고 이 주소에서
페이지 엔트리의 오프셋을 더하면 이 주소가 물리주소가 됩니다.

프로세서는 가상 주소에 접근을 할 때 마다 이 과정을 통해 가상 주소에서 물리 주소로
변환이 되어 접근하게 됩니다.

그리고 몇몇 분들은 눈치를 채셨을테지만, 4GB의 주소를 사용할 수 있다는건 실제 메모리가 2GB 라도
그 이상으로 접근했을 때 페이지 엔트리의 주소만 적당히 바꿔준다면 2GB의 실제 물리메모리에 할당을 해주면 됩니다.

페이징을 사용할 때의 장점은 각각의 태스크가 독립된 공간을 가지고, 서로 이 영역을 침범할 수 없습니다.
또한 같은 프로그램을 실행하는 경우 태스크끼리 같은 코드 영역을 공유하므로 메모리의 공간을 절약할 수 있습니다.
그리고 아래에서 좀 더 설명할 내용이지만 사용하지 않는 페이지는 디스크에 저장하여 실제 메모리보다 더 많은 프로그램을
올릴 수 있습니다.

단점이라면 요즘은 하드웨어에서 지원을 잘 해줘서 문제가 적지만
접근을 할 때마다 주소를 변환해야 하므로 페이징을 사용하기 전보다는 시간이 조금(아주 조금)더 걸립니다.

그리고 주의해야 할 점은 페이지 디렉터리, 테이블, 엔트리의 주소는
4KB로 정렬되어야 한다는 점입니다.

아래에는 각각 페이지 디렉터리 엔트리, 페이지 테이블 엔트리의
각 비트의 역할에 관한 내용입니다.


1. 페이지 디렉터리 엔트리
[Page Table Address][Avail][G][S][0][W][U][R][P]

Page Table Address는 20비트로, 페이지 테이블의 주소를 나타내고
4KB를 곱한 값이 실제 테이블 주소가 됩니다.

Avail은 말 그대로 OS가 임의로 이용이 가능한 부분입니다.

G는 페이지 디렉터리에서는 무시됩니다.

S는 페이지의 크기를 말하고 1로 설정되면 4MB, 0으로 설정되면 4KB 입니다.

0는 

W는 1이라면 Writh-Through 캐시를, 0이라면 Write-Back 캐시를 사용합니다.

A는 Accessed 으로,  페이지가 접근되었다면 프로세서가 1로 설정합니다.
단, 프로세서는 이걸 스스로 지우지 않습니다.

U는 User/Supervisor 으로 1이라면 모든 구역에서 접근이 가능하고
0이라면 특별한 권한을 가진 곳에서만 접근이 가능합니다.

P 비트는 페이지가 현재 메모리상에 존재하는지 여부를 나타냅니다.



// 아래 부분에는 나중에 이론적인 부분을 더 점검하고 페이지 스왑 등의 부분을 더 추가할 예정
