Linux 커널 메모리 관리 참조

Linux 커널 메모리 관리 참조

Linux Device Drivers 책에서 발췌한 내용을 이해하는 데 어려움을 겪고 있습니다(죄송합니다. 이 게시물은 텍스트가 너무 많습니다).

커널(x86 아키텍처에서 기본 구성)은 사용자 공간과 커널 사이에 4GB 가상 주소 공간을 분할합니다. 두 컨텍스트 모두에서 동일한 매핑 세트가 사용됩니다. 일반적인 분할은 사용자 공간에 3GB, 커널 공간에 1GB를 할당합니다.

알았어, 알아.

커널의 코드와 데이터 구조는 해당 공간에 맞아야 하지만커널 주소 공간을 가장 많이 소비하는 것은 물리적 메모리의 가상 매핑입니다.

무슨 뜻이에요? 커널의 코드와 데이터 구조도 "물리적 주소 공간에 매핑된 가상 메모리"에 있지 않습니까? 이러한 코드와 데이터 구조는 어디에 저장되어 있나요?

아니면 드라이버, IPC 또는 기타 수단을 통해 조작하는 커널과 관련되지 않은 임의의 데이터를 매핑하기 위해 커널에 가상 주소 공간이 필요합니까?

커널은 커널 주소 공간에 매핑되지 않은 메모리에서 직접 작동할 수 없습니다. 즉, 커널은 직접 액세스할 수 있는 메모리를 저장하기 위해 자체 가상 주소가 필요합니다.

이거 진짜야? 커널이 프로세스 컨텍스트(시스템 호출 처리)에서 실행 중인 경우 프로세스의 페이지 테이블은 계속 로드되는데 왜 커널이 사용자 모드 프로세스 메모리를 직접 읽을 수 없습니까?

따라서 수년 동안 커널이 처리할 수 있는 최대 물리적 메모리 양은 커널 코드 자체에 필요한 공간을 뺀 커널의 가상 주소 공간 부분에 매핑될 수 있는 양이었습니다.

좋습니다. 제가 인용문 #2를 올바르게 이해했다면 이 말이 이해가 됩니다.

따라서 x86 기반 Linux 시스템은 최대 1GB 미만의 물리적 메모리를 사용할 수 있습니다.

????완전히 비논리적인 것 같습니다. 왜 4GB의 메모리를 사용하고 필요에 따라 다른 것을 커널에 사용 가능한 1GB에 매핑할 수 없습니까? ~1GB의 커널 공간만 있으면 시스템이 4GB로 실행될 수 없다는 것을 의미하는 이유는 무엇입니까? 한꺼번에 매핑할 필요는 없습니다.

답변1

왜 4GB의 메모리를 사용할 수 없고 필요에 따라 다른 것을 커널에 사용 가능한 1GB에 매핑할 수 없습니까?

이는 HIGHMEM직접 매핑에 적합하지 않은 메모리에 대해 구성 옵션이 수행하는 작업입니다. 하지만 이는 메모리의 임의 위치에 액세스해야 할 때 문제가 됩니다.더 쉽게매번 매핑을 설정하지 않고 직접 가리킬 수 있다면 가능합니다. 이를 위해서는 항상 모든 물리적 메모리에 매핑되는 가상 메모리 영역이 필요합니다. 이는 가상 주소 공간이 물리적 주소 공간보다 작은 경우에는 수행할 수 없습니다.

직접 접속도 더 빠르고,vm/highmem.txt커널 문서에서설명하다:

임시 매핑을 만드는 데 드는 비용은 상당히 높을 수 있습니다. 아키텍처는 코어의 페이지 테이블, 데이터 TLB 및/또는 MMU 레지스터를 조작해야 합니다.

물론 사용자 공간 맵을 통해 실행 중인 프로세스의 메모리에 액세스할 수 있으며, 다른 프로세스의 메모리에 액세스하는 것을 피할 수도 있습니다. 그러나 페이지 캐시와 같은 대규모 커널 데이터 구조가 있는 경우 모든 메모리를 사용할 수 있으면 좋을 것입니다.

전체적인 내용이 좀 그렇네요은행 전환, 이는 DOS 시대에 16비트 시스템과 386/486 시스템에서 사용되었던 것입니다(히멤시스템). 나는 그 당시에도 이와 같은 메모리에 액세스하는 것을 특별히 좋아하지 않았다고 생각합니다. 왜냐하면 물리적 메모리의 여러 영역을 동시에 "열어야" 한다면 상황이 꽤 어려워지기 때문입니다. 32비트 시스템으로 발전한 다음 64비트 시스템으로 발전하여 이 문제를 해결했습니다.

답변2

커널이 프로세스 컨텍스트(시스템 호출 처리)에서 실행 중인 경우 프로세스의 페이지 테이블은 계속 로드되는데 왜 커널이 사용자 모드 프로세스 메모리를 직접 읽을 수 없습니까?

이러한 맥락에서 "커널 주소 공간"이라는 용어는 사용자 주소 공간과 반대로 해석되어서는 안 됩니다. 대신, 커널이 액세스해야 하는 메모리가 일부 가상 주소에 매핑되어야 함을 의미합니다. 이 책의 저자가 말하고자 하는 점은 바로 여기에 있다. 따라서 "커널의 주소 공간"은 전체 맵입니다.

답변3

그것은 할 수 있습니다. "몇 년 동안"이 아니라, 그렇게 많은 기억력을 가진 사람이 아무도 없었기 때문에 애초에 그렇게 할 이유가 없었습니다.

계속 읽어보고 주의 깊게 살펴보아야 합니다.

그러나 논리 주소와 직접 매핑할 수 있는 메모리 양에는 여전히 제한이 있습니다. 메모리의 가장 낮은 부분(하드웨어 및 커널 구성에 따라 최대 1GB 또는 2GB)에만 논리 주소가 있고[2] 나머지(더 높은 메모리)에는 없습니다. 특정 대용량 메모리 페이지에 액세스하기 전에 커널은 커널 주소 공간에서 해당 페이지를 사용할 수 있도록 명시적인 가상 매핑을 설정해야 합니다. 따라서 많은 커널 데이터 구조는 낮은 메모리에 배치되어야 합니다. 높은 메모리는 종종 사용자 공간 프로세스 페이지용으로 예약됩니다.


커널이 프로세스 컨텍스트(시스템 호출 처리)에서 실행 중인 경우 프로세스의 페이지 테이블은 계속 로드되는데 왜 커널이 사용자 모드 프로세스 메모리를 직접 읽을 수 없습니까?

물론

https://www.quora.com/Linux-Kernel-How-does-copy_to_user-work


kmalloc()일반적으로 커널에 할당된 구조를 사용하면 직접 매핑된 범위 내에서 약 1GB의 메모리가 반환된다는 점을 아는 것도 유용할 수 있습니다. 그래서 귀엽고 접근하기 쉽습니다.

(비용은 이러한 다양한 유형의 할당 형태로 인해 복잡성이 발생한다는 것입니다.

표준 kmalloc()할당이 RAM의 25% 이상을 사용할 수 있도록 하려면 다소 까다로운 작업을 수행해야 합니다... 더 특별한 경우에는 GFP_HIGHMEM 플래그를 설정하고 필요에 따라 메모리를 매핑 및 매핑 해제할 수 있습니다. 그러나 공식적인 대답은 30비트 이상의 물리적 RAM을 갖춘 기존 32비트 시스템에서 이렇게 까다로운 작업 부하를 실행해서는 안 된다는 것입니다.

이 특정 세부 사항에 정말로 관심이 있다면 두 가지 다른 점을 발견했습니다.

1. 1GB 제한하다RAM에 제한을 두되 조금 더 높이십시오.

https://www.redhat.com/archives/rhl-devel-list/2005-January/msg00092.html

인터넷 검색에 따르면 대용량 RAM(예: 32GB 이상)이 있는 시스템에는 커널 메모리 테이블이 물리적 메모리 크기에 따라 확장되므로 4G:4G 패치가 필요한 반면, 32GB 시스템은 3G:1G 시스템에서 사용 가능한 0.5GB 테이블을 사용하는 것으로 나타났습니다. 커널 공간의 절반. 64GB 시스템은 테이블에 모든 커널 메모리가 필요하므로 부팅할 수 없습니다.

4G: 4G 패치는 또 다른 이야기입니다. 하지만 메인라인 Linux에는 없으므로 무시해도 됩니다.

이제 CONFIG_HIGHMEM64G를 활성화할 수 있으므로(i386, 즉 32비트) 이러한 제한도 극복된 것 같습니다. 아마도 이것에 의존하지 않는 것이 가장 좋습니다. 아니면 무엇을 해야 할지 너무 열심히 생각하세요.

2. 페이지 테이블에는 직접 매핑이 엄격하게 요구되지 않습니다.

많은 인기 있는 운영 체제 작성 튜토리얼과 연습에서는 "재귀 페이지 테이블"이라는 흥미로운 기술을 사용합니다.

https://www.google.co.uk/search?q=recursive+page+tables

Linux는 이 방법을 사용하지 않으므로 기존 Linux가 이해하기 더 쉽습니다. ~1GB "낮은 메모리"의 직접 매핑은 초기 페이지 테이블에 설정되며 변경되지 않습니다. 페이지 테이블은 "낮은 메모리"에서 할당됩니다.

(CONFIG_HIGHMEM64G가 지금 무엇을 하는지 궁금하십니까? 중지하십시오. 이는 귀하에게 좋지 않습니다.)

나는 Linus가 재귀적 트릭을 전혀 생각하지 않았다고 생각합니다. IIRC에는 적절한 크기의 직접 지도가 없다는 점에서 다른 단점이 있지만 구체적인 예는 확실하지 않습니다.

나는 "전통적인 리눅스"라고 말했습니다. KPTI가 실제로 32비트로 병합되었는지는 들어본 적이 없지만... 그럼에도 불구하고 KPTI가 전반적인 아이디어를 바꾸면 안 됩니다. 사용자 페이지 테이블에서 커널 페이지 테이블로 전환하면 커널이 직접 매핑에 액세스할 수 있습니다. 전환 프로세스는 멋진 흑마술이지만 모든 컨텍스트 전환에서 수행됩니다. 사용자 공간 페이지 테이블에는 직접 매핑이 포함되지 않지만 사용자 공간은 페이지 테이블 등에 액세스할 수 없으며 액세스해서는 안 됩니다. 따라서 모든 것이 정상입니다.

관련 정보