Highmem과 Lowmem의 차이점에 관심이 있습니다.
- 왜 그런 차별화가 있습니까?
- 그렇게함으로써 우리는 무엇을 얻습니까?
- 각 기능에는 어떤 기능이 있습니까?
답변
32 비트 아키텍처에서 RAM 주소 지정을위한 주소 공간 범위는 다음과 같습니다.
0x00000000 - 0xffffffff
또는 4'294'967'295
(4GB).
리눅스 커널은 3/1 (2/2 또는 1/3 1 일 수 있음 )을 각각 사용자 공간 (높은 메모리)과 커널 공간 (낮은 메모리)으로 나눕니다.
사용자 공간 범위 :
0x00000000 - 0xbfffffff
새로 생성 된 모든 사용자 프로세스는이 영역 내의 주소 (범위)를 얻습니다. 사용자 프로세스는 일반적으로 신뢰할 수 없으므로 커널 공간에 액세스 할 수 없습니다. 또한, 일반적으로 커널은 이러한 프로세스에 대한 메모리 할당을 연기하려고합니다.
커널 공간 범위 :
0xc0000000 - 0xffffffff
커널 프로세스는 여기서 주소 (범위)를 얻습니다. 커널은이 1GB의 주소에 직접 액세스 할 수 있습니다 (전체 1GB가 아니라 높은 메모리 액세스를 위해 128MB가 예약되어 있음).
커널 공간에 생성 된 프로세스는 신뢰할 수 있고 긴급하며 오류가없는 것으로 가정되며 메모리 요청은 즉시 처리됩니다.
원하는 경우 모든 커널 프로세스가 사용자 공간 범위에 액세스 할 수도 있습니다. 이를 위해 커널은 사용자 공간 (고용량 메모리)에서 커널 공간 (저용량 메모리)으로 주소를 매핑합니다. 위에서 언급 한 128MB는이를 위해 특별히 예약되어 있습니다.
1 분할이 3/1, 2/2 또는 1/3인지 여부는 CONFIG_VMSPLIT_...
옵션에 의해 제어됩니다 . /boot/config*
커널에서 어떤 옵션이 선택 되었는지 확인할 수 있습니다 .
답변
가장 먼저 언급 할 부분은 Linux 장치 드라이버 (온라인 및 책 형식으로 제공), 특히 주제에 대한 섹션이있는 15 장 입니다.
이상적인 세계에서 모든 시스템 구성 요소는 액세스해야하는 모든 메모리를 매핑 할 수 있습니다. 32 비트 프로세스는 2 ^ 32 바이트 미만의 가상 메모리 (사실 일반적인 Linux 32 비트 아키텍처에서는 약 3GB)에만 액세스 할 수 있습니다. 커널은 시스템 호출이 실행중인 프로세스의 전체 메모리와 전체 물리적 메모리 및 기타 메모리 매핑 된 하드웨어 장치를 매핑 할 수 있어야합니다.
따라서 32 비트 커널이 4GB 이상의 메모리를 매핑해야하는 경우 높은 메모리 지원으로 컴파일해야합니다. 높은 메모리는 커널의 주소 공간에 영구적으로 매핑되지 않은 메모리입니다. (낮은 메모리는 반대입니다. 항상 매핑되므로 포인터를 역 참조함으로써 커널에서 액세스 할 수 있습니다.)
커널 코드에서 높은 메모리에 액세스 할 때 kmap
페이지 데이터 구조 ( struct page
) 에서 포인터를 얻으려면 먼저 호출해야합니다 . kmap
페이지가 메모리가 많거나 부족한 경우 호출이 작동합니다. 또한이 kmap_atomic
제약 조건을 추가하지만 세분화 된 잠금을 사용하기 때문에 멀티 프로세서 시스템에서 더 효율적입니다했다한다. 통해 얻은 포인터 kmap
는 리소스입니다. 주소 공간을 사용합니다. 완료 한 후에는 해당 리소스를 확보하기 위해 전화 kunmap
(또는 kunmap_atomic
) 해야합니다 . 포인터가 더 이상 유효하지 않으며 kmap
다시 호출 할 때까지 페이지의 내용에 액세스 할 수 없습니다 .
답변
이것은 Linux 커널과 관련이 있습니다. 유닉스 커널이 이것을 어떻게 처리하는지 잘 모르겠습니다.
높은 메모리는 사용자 공간 프로그램이 처리 할 수있는 메모리 세그먼트입니다. 메모리 부족을 건드릴 수 없습니다.
메모리 부족은 Linux 커널이 직접 처리 할 수있는 메모리 세그먼트입니다. 커널이 높은 메모리에 액세스해야하는 경우 먼저 자체 주소 공간에 매핑해야합니다.
최근에 도입 된 패치로 세그먼트의 위치를 제어 할 수 있습니다. 단점은 사용자 공간에서 주소 지정 가능한 메모리를 가져 와서 커널이 사용하기 전에 매핑 할 필요가없는 더 많은 메모리를 가질 수 있다는 것입니다.
추가 자료 :
답변
HIGHMEM은 커널의 메모리 공간 범위이지만 액세스하는 메모리는 아니지만 액세스하려는 것을 넣는 장소입니다.
일반적인 32 비트 Linux 가상 메모리 맵은 다음과 같습니다.
-
0x00000000-0xbfffffff : 사용자 프로세스 (3GB)
-
0xc0000000-0xffffffff : 커널 공간 (1GB)
(CPU 별 벡터 및 그 밖의 내용은 여기에서 무시됩니다).
Linux는 1GB 커널 공간을 LOWMEM 및 HIGHMEM의 두 조각으로 나눕니다. 분할은 설치마다 다릅니다.
설치가 LOW 및 HIGH mems에 대해 512MB-512MB를 선택하면 512MB LOWMEM (0xc0000000-0xdfffffff)이 커널 부팅시 정적으로 매핑됩니다. 일반적으로 물리 메모리의 첫 번째 바이트가이를 위해 사용되므로이 범위의 가상 주소와 물리 주소는 0xc0000000과 같은 일정한 오프셋을 갖습니다.
반면, 후자의 512MB (HIGHMEM)에는 정적 매핑이 없습니다 (페이지를 반영구적으로 매핑 할 수는 있지만 드라이버 코드에서 명시 적으로 그렇게해야 함). 대신이 범위의 가상 주소와 실제 주소에 일관된 매핑이 없도록 페이지가 임시로 매핑되고 매핑이 해제됩니다. HIGHMEM의 일반적인 사용에는 단일 시간 데이터 버퍼가 포함됩니다.
답변
내가 기억하는 한, “High Memory”는 응용 프로그램 공간에 사용되고 “Low Memory”는 커널에 사용됩니다.
장점은 (사용자 공간) 응용 프로그램이 커널 공간 메모리에 액세스 할 수 없다는 것입니다.
답변
많은 사람들은 메모리 부족이 운영 체제를위한 것이라고 말합니다. 이것은 일반적으로 사실이지만 반드시 그럴 필요는 없습니다. 높은 메모리와 낮은 메모리는 메모리 공간의 두 부분에 불과하지만 Linux 시스템에서 낮은 메모리는 커널 전용이며 사용자 프로세스의 높은 메모리입니다.
“공룡 책 (운영 체제 개념)”에 따르면, 운영 체제를 메모리 부족 또는 고용량 메모리에 배치 할 수 있습니다. 이 결정에 영향을 미치는 주요 요인은 인터럽트 벡터의 위치입니다. 인터럽트 벡터는 종종 메모리가 부족하기 때문에 프로그래머는 일반적으로 운영 체제도 메모리가 부족합니다.