ZONE_NORMAL 및 커널/사용자 페이지와의 연관성은 무엇입니까?

ZONE_NORMAL 및 커널/사용자 페이지와의 연관성은 무엇입니까?

차트

위 내용은 실제 메모리가 512MB만 있는 상황을 설명합니다. 지금까지 내가 읽은 것은 ZONE_NORMAL이 표시된 대로 커널 가상 주소 공간에 매핑된다는 것입니다. 본질적으로 나는 512MB의 물리적 메모리를 가지고 있으며 그 중 496MB는 커널 가상 공간에 매핑된 ZONE_NORMAL입니다. 이러한 이해를 바탕으로 내 질문은 다음과 같습니다.

  • ZONE_NORMAL에 다음이 포함되어 있습니까?오직커널 공간 페이지?
  • ZONE_NORMAL이 커널 페이지로만 구성되어 매핑된 경우완전히커널 공간 가상 주소 범위에서 사용자 공간 페이지는 어디에 있습니까? 사용자 공간 페이지를 위한 물리적 메모리 공간이 없는 것 같습니다.

제가 제시한 사례에서 보듯이 물리적 메모리가 4GB 미만인 경우는 완전히 혼란스럽습니다.

누구든지 이것에 대해 밝힐 수 있다면 매우 감사하겠습니다.

답변1

32비트 아키텍처에서는 물리적 주소를 참조하기 위한 선형 주소(물리적 공간 아님) 0xffffffff( 4'294'967'295또는 4GB)가 있습니다.
물리적 저장소(버스에 연결된 실제 RAM 스틱)가 512MB만 있어도 커널은 여전히 4'294'967'295​​(4GB) 선형 주소를 사용하여 물리적 주소를 계산합니다.

Linux 커널은 이 4GB(주소)를 사용자 공간(높은 메모리)과 커널 공간(낮은 메모리)으로 3/1로 나누므로 커널 공간에는 1'073'741'823사용할 수 있는 선형 주소(1GB)가 있습니다.

이 1GB의 선형 주소는 커널에서만 액세스할 수 있으며 더 세분화됩니다.

Area_DMA: 16MB보다 작은 메모리 페이지 프레임을 포함합니다. 이는 RAM의 처음 16MB만 주소를 지정할 수 있는 구형 ISA 버스에 사용되었습니다.

면적_보통: 16MB 이상 및 896MB 미만의 메모리 페이지 프레임을 포함하며 커널이 직접 매핑/액세스할 수 있는 주소입니다.

ZONE_HIGHMEM: 896MB 이상의 메모리 페이지 프레임을 포함합니다. 이 경계 위의 페이지 프레임은 일반적으로 커널 공간에 매핑되지 않으므로 커널에서 직접 액세스할 수 없습니다. 사용자 공간의 페이지 프레임은 여기에 일시적으로 또는 영구적으로 매핑될 수 있습니다.

다양한 지역에서 차지하는 실제 물리적 RAM 공간의 양은 실행 중인 프로세스의 형태와 수에 따라 다릅니다.

free -ml콘솔에 입력 하면 낮은 메모리와 높은 메모리의 사용량을 모두 볼 수 있습니다.

             total       used       free     shared    buffers     cached
Mem:          3022       2116        905          0        105       1342
Low:           839        196        642
High:         2182       1919        263
-/+ buffers/cache:        667       2354
Swap:         2859         93       2766

답변2

동일한 물리적 페이지를 여러 가상 주소에 매핑할 수 있습니다.

ZONE_NORMAL은 매핑할 수 있는 페이지로 구성됩니다.통과핵심. 대부분의 메모리는 커널에 속하지 않지만 커널은 특정 시점에 모든 메모리를 매핑해야 합니다(모두 동시에는 아님). 예를 들어, 커널이 write시스템 호출을 처리할 때 사용자 제공 버퍼에서 데이터를 복사해야 합니다. 즉, 버퍼가 커널의 가상 주소 공간에 매핑되어야 합니다.

다이어그램은 높은 메모리가 없는 (비교적) 간단한 사례를 보여줍니다. (고급 ARM 장치를 사용하고 있다면 지금이 대용량 메모리에 대해 학습할 때입니다.) 그러면 커널은 모든 프로세스 메모리와 모든 물리적 메모리를 동시에 매핑할 수 있습니다.

다음은 커널 코드에서 볼 수 있는 가상 메모리 재분할의 예입니다(정확한 숫자가 가능한지는 확실하지 않지만 기본 아이디어는 정확해야 합니다). 즉, 커널 코드에서 사용하는 포인터의 의미를 설명하는 것입니다.

  • 0x00000000..0x00000fff: 할당되지 않았습니다. 이 범위 내의 포인터는 유효하지 않습니다.
  • 0x00001000..0xbfffffff: 프로세스 메모리. 이는 고려 중인 커널 코드가 시스템 호출을 처리하는 프로세스의 가상 주소 공간에 대한 포인터입니다. 해당 범위의 페이지는 할당되지 않거나 RAM에 할당 및 스왑되거나(물리적 주소가 있는 경우) 할당 및 스왑 아웃될 수 있습니다(물리적 주소가 없는 경우). 그것은 스왑에 있습니다. )에 위치가 있습니다.
  • 0xc0000000..0xdfffffff: 물리적 메모리. 이 범위의 포인터는 물리적 주소 p-0xc0000000을 나타냅니다. 이 포인터의 해석은 실제로 MMU에 의존하지 않습니다.
  • 0xe0000000..0xffefffff: 할당되지 않았습니다. 이 범위 내의 포인터는 유효하지 않습니다.
  • 0xff000000..0xffffffff: 커널 메모리. 이는 커널 코드나 데이터에 대한 포인터입니다. 이 범위의 페이지에는 MMU에서 찾은 연결된 물리적 주소가 있습니다.

내가 찾은리눅스 장치 드라이버Linux 커널의 내부 구조에 대한 좋은 소개입니다. 궁극적으로 다음으로 전환하고 싶을 수도 있습니다.원천.

관련 정보