페이징을 위해 먼저 A20 게이트의 설명
- A20게이트를 0으로 클리어 하면 홀수 MB 메모리가 짝수 MB와 2진수 값이 같아진다 -> A20을 켜지 않으면 홀수 MB를 사용할 수 없다.
- A20게이트가 0으로 되어있다는것은 메모리 값의 2진수 표현이 1FFFFF라면 1 1111 1111 1111 1111 1111 이 0 1111 1111 1111 1111 1111 이되는 것이다. 이것은 과거 8086이 1MB의 주소를 사용한, 20개의 어드레스 라인을 가지고 있었기 때문이다.(즉 0부터 19번 비트까지) CPU가 발달하면서 08286이 24개의 어드레스 라인을 사용했지만 과거 프로그램과의 호환을 위해(1MB가 넘으면 다시 0부터 시작하는 메 모리 방식) 20번 비트를 키보드 컨트롤러의 특정 비트와 AND로 물려놓아 이 키보드 컨트롤러가 1로 셋트되어야만 20번 비트가 제대로 의미를 가질 수 있게 해놓았다.
- 따라서 주소지정을 올바르게 (홀수MB와 짝수 MB를 모두 사용하려면) 사용하려면 A20게이트를 열어놓아야 한다.(아마 요즘은 전혀 필요 없을듯)
예) 1MB는 16진수 -> 0x100000 2진수 -> 1 0000 0000 0000 0000 0000 A20 게이트가 켜져있지 않다면 이 값은 0
2MB는 16진수 -> 0x200000 2진수 -> 10 0000 0000 0000 0000 0000 A20게이트가 켜져있지 않아도 값은 같다.
3MB는 16진수 -> 0X300000 2진수 -> 11 0000 0000 0000 0000 0000 A20게이트가 켜져있지 않다면 이 값은 2MB와 같다.
○ 페이징은 논리주소 -> 선형주소 -> 물리주소의 과정을 거친다.
○ 32비트 시스템에서는 주소를 32비트로 표현한다. 이 32비트 주소는 페이징의 선형주소에 의해 10 비트 10 비트 12비트로 분할되어 각각 의미를 가진다.
페이지디렉토리 엔트리 번호(10비트) |
페이지 테이블 엔트리 번호(10비트) |
물리페이지의 offset(12비트) |
○ 보호모드를 지원하는 CPU는 CR3 레지스터를 가지는데 이것이 페이지 '디렉토리'의 시작주소를 가진다.
○ 페이지 '디렉토리' 엔트리는...각 페이지 '테이블'의 시작주소의 포인터(주소)를 가진다
'디렉토리'는 1024개(2의 10승->10비트)의 엔트리를 가지고 있다.
마찬가지로 페이지 '테이블'은 각 물리페이지 시작주소를 포인터로 가지고 역시 1024개의 엔트리를 가진다.
○ 페이지'테이블'의 엔트리와(물리페이지의 시작주소) 12비트 offset을 합치면 실제 물리주소가 나오게 된다.
물리페이지의 offset만 12비트인 이유는 각 페이지는 4KB로 모두 잘라져있는데(페이징이선 크기를 모두 4KB로 자른다. 페이지 디렉토리도 4KB 이고 페이지 테이블도 4KB이며 각 물리페이지도 4KB로 램상에 차지한다.) 이 4KB가 4098byte 이고 이것은 2의 12승이다. 따라서 offset이 12비트면 4KB의 영역을 바이트 단위로 접근할 수 있는것이다.
(역으로 생각해보면 모든 페이지가 4KB단위이므로 4098byte -> 2^12승(byte) -> 2^12승은 16진수로 3칸(?)을 차지한다. 즉 모든 물리페이지는 항상 하위 3자리가 000으로 끝난다. 0x00002000, 0x00008000 등등. 이것이 테이블 엔트리나 디렉토리 엔트리에서 주소지정을 할때 20비트만 사용하는 이유이다.뒷 주소가 0xffffff000 이므로 뒤의 세자리(즉 2의 12승)는 항상 0이라고 생각하고 나머지 5자리 즉 20비트만 필요한것이다. )
○ 결과적으로 디렉토리와 테이블 엔트리의 곱 1024*1024 = 1MB 이고 각각 4KB의 페이지를 가지고 있으므로 1MB*4KB = 4GB 즉 메모리 지정을 4GB까지 할 수 있다.
○ 프로그램에서 요구되는 32bit주소를 찾아가는 순서(페이지 디렉토리를 가리키는 첫번째 10비트를 A, 페이지 테이블을 가리키는 두번째 10비트를 B, 물리페이지 offset의 12비트를 C라 하면)
- CR3의 주소를 참조해 페이지 디렉토리의 시작주소를 찾아간다.
- 요구된 주소의 'A'와 디렉토리의 시작주소를 더하면 이 값이 1024개의 테이블중 하나를 가리키는 주소가 된다.(따라서 이 최상위 10비트는 디렉토리의 'offset'이다)
- 테이블의 시작주소를 얻었으므로 이 주소와 'B'를더한다. 이 더한값은 물리페이지의 시작주소가 된다.(물리페이지는 4KB)
- 이 물리페이지의 시작주소와 'C'를 결합하면 4KB 페이지 안의 실제 메모리 물리 주소가 나오게 된다.
○ 페이지 디렉토리는 각 프로세스마다 존재하고 페이지 디렉토리의 시작주소는 mm_struct 구조체의 pgd필드가 가 가진다... 여기에 적힌 주소는 가상 주소가 아니라 물리주소이다. 페이징을 해야하면(주소가 요청되면) 이 주소가 cr3에 들어간다..
[출처] 메모리 페이징