저는 Linux 3/1 분할(또는 2/2, 1/3 등)과 물리적 메모리에 대한 매핑이 어떻게 작동하는지 이해하려고 노력하고 있습니다. x86을 가정해 봅시다.
특히 내가 이해하지 못하는 것은 커널의 va[3GiB, 4GiB)에서 1GiB가 항상 pa[0, 1GiB]에 매핑되는 이유입니다. 분할 위치는 (가상) 입니다 PAGE_OFFSET
.
메모리가 더 많으면 어떻게 되나요? 내가 가진 것이 적다면 어떻게 될까요? 사용자 공간의 모든 메모리는 어디로 가나요?
TLDP에서 나는 하단 물리적 1GiB가 항상 커널에 사용된다는 것을 알고 있습니다(왜?). 높은 메모리 사용(이 글을 통해) 가상 주소 공간이 물리적 주소 공간보다 작은 경우에는 낭비될 메모리가 많기 때문에(맞습니까?) x86-64에서는 가상 주소 공간이 이상하기 때문에 사용되지 않습니다.
커널에 항상 남아 있는 한 가지는 컨텍스트 스위치에서도 동일하게 유지되며 current
변경할 필요가 없다는 것입니다 cr3
.
이 답변설명하다:
대용량 메모리는 사용자 공간 프로그램이 주소를 지정할 수 있는 메모리 세그먼트입니다. 메모리 부족을 건드릴 수 없습니다.
낮은 메모리는 Linux 커널이 직접 해결할 수 있는 메모리 세그먼트입니다. 커널이 높은 메모리에 액세스해야 하는 경우 먼저 이를 자체 주소 공간에 매핑해야 합니다.
사람들이 "낮은 메모리"와 "높은 메모리"라는 용어를 남용합니까?
마지막으로 LDD3은 이렇게 말했습니다.
커널은 커널 주소 공간에 매핑되지 않은 메모리에서 직접 작동할 수 없습니다. 즉, 커널은 직접 액세스할 수 있는 메모리를 저장하기 위해 자체 가상 주소가 필요합니다. 따라서 수년 동안 커널이 처리할 수 있는 최대 물리적 메모리 양은 커널 코드 자체에 필요한 공간을 뺀 커널의 가상 주소 공간 부분에 매핑될 수 있는 양이었습니다. 따라서 x86 기반 Linux 시스템은 최대 1GB 미만의 물리적 메모리를 사용할 수 있습니다.
p
이것은 매핑이 항상 적용되는 것처럼 커널의 포인터가 물리적 주소가 아닌 가상 주소를 보유해야 한다는 것을 의미합니까? "1GiB 물리적 메모리" 제한이 있는 이유는 무엇입니까?
답변1
오늘날 32비트 x86은 Linux가 탄생한 1990년대 초반의 16비트 8086만큼 쓸모가 없습니다. 당시에는 386에서 제공하는 4GB의 가상 주소 공간이면 충분했습니다. 일반적인 데스크톱 컴퓨터에는 수십 개의 주소 공간밖에 없었기 때문입니다.메가바이트메모리.
Linus는 가상 주소 공간을 분할하여 상위 1GB(주소 0xc0000000에서 시작)를 커널용으로 예약하고 하위 3GB(주소 0에서 시작)를 사용자 공간 프로세스에 사용할 수 있도록 결정했습니다. 그런 다음 모든 물리적 RAM은 3GB부터 시작하는 주소인 PAGE_OFFSET부터 매핑됩니다. (앞서 언급했듯이) 일반적인 물리적 RAM 용량이 그보다 훨씬 적었고, 이 분할로 인해 사용자 공간으로 편안한 3GB가 남았기 때문에 당시에는 1GB이면 충분했습니다.
페이징이 활성화되기 전에(즉, 가상-물리적 주소 매핑) 커널 코드와 정적 데이터가 포함된 커널 이미지가 물리적 메모리의 시작 부분에 로드됩니다. (정확하지는 않지만 PC 플랫폼의 일부 특성으로 인해 일반적으로 2MB에서 시작합니다.) 페이징이 활성화되면 물리적 주소 N의 메모리는 가상 주소 N + PAGE_OFFSET에서 끝납니다. 이는 커널 이미지가 커널 메모리 영역의 낮은 부분(일반적으로 몇 메가바이트)을 차지함을 의미합니다.
지금까지 가상 주소 공간에 대해 설명했습니다.예약된특정 것들에 대해서는. 실제로 이러한 주소를 사용하려면 물리적 RAM 페이지 프레임을 가상 주소에 매핑해야 합니다. 초기에는 매핑에 사용할 수 있는 물리적 RAM이 너무 적기 때문에 커널 가상 주소 공간의 작은 부분만 매핑되었지만 더 큰 RAM이 저렴해지면서 이는 빠르게 급격하게 바뀌어 1GB가 되었습니다. 모든 주소를 처리할 공간이 부족합니다. RAM. 따라서 필요에 따라 일부 추가 RAM을 매핑할 수 있는 창을 제공하는 "고용량 메모리" 메커니즘이 도입되었습니다.
그렇다면 커널의 가상 주소 공간에 RAM이 필요한 이유는 무엇입니까? 문제는 CPU가 가상(매핑된) 주소를 통해서만 메모리(프로그래밍 방식으로)에 액세스할 수 있다는 것입니다. 레지스터의 포인터는 프로그램 흐름을 안내하는 명령어 포인터와 마찬가지로 가상 주소 공간에 대한 포인터입니다. 커널은 나중에 사용자 공간 프로세스에 제공되는 버퍼를 제로화하는 등 RAM에 자유롭게 액세스할 수 있어야 합니다.
커널이 전체 RAM을 주소 공간에 저장한다고 해서 사용자 공간이 이에 액세스할 수 없다는 의미는 아닙니다. RAM 페이지 프레임에 대한 여러 매핑이 존재할 수 있습니다. 프로세스가 실행을 위해 선택되면 커널 메모리 공간이나 사용자 공간의 주소에 영구적으로 매핑될 수 있습니다.