64비트 Linux 커널은 호환 모드에서 32비트 응용 프로그램의 페이지 테이블을 어떻게 관리합니까?

64비트 Linux 커널은 호환 모드에서 32비트 응용 프로그램의 페이지 테이블을 어떻게 관리합니까?

현재 저는 "Linux 커널 이해"라는 책을 읽고 있습니다. 그 중에는 다음과 같은 진술이 있습니다.

물리적 주소 확장이 없는 32비트 아키텍처의 경우 두 개의 페이징 수준이면 충분합니다. Linux에서는 기본적으로 Directory-on-Page 및 Directory-in-Page 필드가 0비트를 포함하므로 제거됩니다. 그러나 포인터 시퀀스에서 페이지 상위 디렉터리와 페이지 중간 디렉터리의 위치는 유지되므로 동일한 코드가 32비트 및 64비트 아키텍처에서 작동할 수 있습니다. 커널은 페이지의 상위 디렉토리와 페이지의 중간 디렉토리의 항목 수를 1로 설정하고 이 두 항목을 페이지의 전역 디렉토리에 있는 올바른 항목에 매핑하여 페이지의 상위 디렉토리와 페이지의 중간 디렉토리의 위치를 ​​보존합니다.

따라서 4단계 페이징 수준을 갖춘 64비트 Linux 커널의 페이지 테이블 계층 구조는 다음과 같습니다.

PML4 (Linux: PGD) -> 512 * PDPT (Linux: PUD) -> 512 * PD (Linux: PMD) -> 512 * PT

따라서 텍스트에서는 두 가지 수준이면 충분하다고 합니다(일반적인 32비트 페이징과 마찬가지로). 이것이 바로 PUD와 PMD가 "제거"되는 이유이지만 이 두 테이블 중 하나의 길이가 1이고 시퀀스에서 올바른 순서를 저장합니다. .
내 이해에 따르면 이는 PML4(PGD)가 PD(PMD)에 해당하고 PT에 대한 직접 포인터로 구성된다는 의미입니다. 따라서 PUD 및 PMD는 "건너뜁니다". 하지만 이는 올바르지 않은 것 같습니다. 모드를 커널 모드로 전환한 후 커널 페이지에 액세스하려면 64비트 페이지 테이블을 사용하여 페이징을 수행해야 하기 때문입니다. 또한 이 매핑 구성표는 4GB 경계(예: 커널 페이지)를 초과하는 메모리 매핑을 허용하지 않습니다.
또 다른 설명은 32비트 주소가 64비트로 0 확장되고 계층 구조의 처음 두 테이블에 대해 첫 번째 항목이 사용된다는 것입니다. 그런 다음 나머지 비트를 사용하여 나머지 두 테이블의 항목과 페이지 프레임 내의 오프셋을 선택할 수 있습니다. 그러나 각 테이블 항목의 비트 수가 32비트 모드와 64비트 모드에서 다르기 때문에 이것도 정확하지 않은 것 같습니다. 따라서 이로 인해 문제가 발생할 수도 있습니다.
그렇기 때문에 제가 고려하지 못한 부분이 있었나 봐요. 누군가가 상황을 명확히 할 수 있기를 바랍니다.

답변1

첫째, 이와 같은 64비트 시스템에서는 32비트 실행 파일을 실행할 수 없습니다. 따라서 32비트 주소를 64비트 주소 등으로 변환할 필요가 없습니다.

둘째, 32비트(PAE 없음)는 4GB 경계를 넘는 메모리 매핑을 전혀 허용하지 않습니다.

이 질문에 대해 많이 고민했고, 여러 번 읽어보면서 답을 찾았습니다. StackOverflow에서 비슷한 질문을 본 적이 있을 것입니다.Linux 커널 메모리 관리 페이징 수준

하지만 나는 그것을 어떻게 이해하는지 설명하려고 노력합니다. 제가 설명하려는 것은 32비트 시스템에서 4단계 페이징이 작동하는 방식입니다.

첫 문장이 정말 중요해요

[...] 페이지 디렉터리 및 페이지 디렉터리 필드에 0비트가 포함되어 있다고 말하여 이를 제거합니다.

이것은 커널을 의미하지 않습니다.세트이 필드들은 0인데, 이 필드들이 0이라고 되어 있지만 어딘가에는 이를 표현하지 않습니다. 따라서 2레벨 페이징에 일반적인 32비트 주소 분리를 사용할 수 있습니다.

이는 PML4 가상 주소(Linux: PGD)의 최상위 10비트를 사용한다는 의미입니다.

PML4(Linux: PGD)는 항목이 하나만 있는 PDPT(Linux: PUD)를 가리킵니다. 커널에서는 인덱스/오프셋이 0이라고 말하기 때문에 이 항목만 사용됩니다.

PDPT(Linux: PUD)에 대한 유일한 항목은 PD(Linux: PMD)를 가리키며, 이 항목에도 항목이 하나만 있습니다. 다시 커널은 인덱스/오프셋이 0이라고 명시하므로 해당 항목만 사용됩니다.

마지막으로 PD(Linux: PMD)에 대한 고유 항목은 PT를 가리키며, 여기서 가상 주소의 중간 10비트는 원하는 페이지를 찾기 위한 인덱스로 사용됩니다.

간단히 말해서:

[1024 *] PML4 (Linux: PGD) -> 1 * PDPT (Linux: PUD) -> 1 * PD (Linux: PMD) -> 1024 * PT

관련 정보