Linux 드라이버는 "커널" 공간에서 실행됩니다. 일반적으로 드라이버는 kmalloc()를 호출하여 데이터 구조에 대한 메모리를 할당하고, vmalloc()를 호출하여 활성 스왑 영역에 대한 데이터 구조를 할당하거나, 일부 I/O 드라이버에 대한 버퍼를 할당하거나, kmalloc 및 vmalloc이 커널 메모리를 할당할 공간을 할당합니다.
이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.
Linux 드라이버는 "커널" 공간에서 실행됩니다.
일반적으로 작성된 마이크로 컨트롤러 프로그램의 경우 애플리케이션과 드라이버가 혼합되는 경우가 많습니다. 일정 수준의 능력을 갖춘 마이크로 컨트롤러 프로그래머는 애플리케이션과 드라이버의 계층화를 실현할 수 있습니다. Linux 시스템에서는 애플리케이션과 드라이버가 강제로 계층화되었습니다.
마이크로 컨트롤러 프로그램에서 애플리케이션은 기본 레지스터를 직접 작동할 수 있습니다. 그러나 Linux 시스템에서는 이러한 동작이 금지됩니다. 예를 들어 Linux 애플리케이션 작성자는 의도적으로 애플리케이션에서 전원 관리 드라이버를 호출하고 시스템을 종료할 가치가 있지 않습니까?
특정 Linux 애플리케이션은 그림에 표시된 대로 드라이버를 호출합니다.
애플리케이션은 사용자 공간에서 실행되고 드라이버는 커널 공간에서 실행됩니다. 사용자 공간의 애플리케이션이 커널을 동작시키려면 사용자 공간에서 커널 공간으로 진입해 최하위 계층을 동작시키기 위해 '시스템 호출' 방식을 거쳐야 한다.
커널도 프로그램이므로 자체 가상 메모리 공간도 있어야 합니다. 그러나 사용자 프로그램을 서비스하는 프로그램으로서 커널 공간에는 고유한 특성이 있습니다.
커널 공간과 사용자 공간의 관계
32비트 시스템에서 프로그램의 가상 공간은 최대 4GB까지 가능하므로 가장 직접적인 방법은 커널을 프로그램으로 간주하여 만드는 것입니다. 다른 프로그램과 마찬가지로 4GB의 공간도 있습니다. 그러나 이 접근 방식은 시스템이 사용자 프로그램의 페이지 테이블과 커널 페이지 테이블을 지속적으로 전환하게 하여 컴퓨터의 효율성에 영향을 미칩니다. 이 문제를 해결하는 가장 좋은 방법은 4GB 공간을 두 부분으로 나누는 것입니다. 한 부분은 사용자 공간이고 다른 부분은 커널 공간입니다. 이렇게 하면 커널 공간이 고정되고 변경되지 않고 프로그램이 전환될 때 프로그램 변경. 이 접근 방식의 유일한 단점은 커널 공간과 사용자 공간이 모두 작아진다는 것입니다.
예: i386과 같은 32비트 하드웨어 플랫폼에서 Linux는 page.h 파일에 상수 PAGE_OFFSET을 정의합니다.#ifdef CONFIG_MMU #define __PAGE_OFFSET (0xC0000000) //0xC0000000为3GB #else #define __PAGE_OFFSET (0x00000000) #endif #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
Linux는 PAGE_OFFSET을 경계로 사용하여 4GB 가상 메모리 공간을 두 부분으로 나눕니다. 0부터 3G-1까지의 낮은 주소 공간은 3GB 크기의 사용자 공간이고, 3GB부터 4GB-1까지의 높은 주소 공간은 1GB 크기의 커널 공간입니다.
시스템에서 여러 프로그램이 실행 중인 경우 여러 사용자 공간과 커널 공간의 관계는 다음과 같이 표현할 수 있습니다. 그림과 같이 프로그램 1, 2...n이 커널 공간을 공유합니다. . 물론 여기서 공유는 시간 공유를 의미합니다. 단일 코어 프로세서 시스템의 경우 언제든지 하나의 프로그램만 실행할 수 있기 때문입니다.커널 공간의 전체 레이아웃
리눅스의 개발 과정에서 하드웨어 장비의 업데이트와 기술 수준의 향상에 따라 커널 공간 레이아웃의 개발도 지속적인 패치의 한 방법입니다. 그 결과 커널 공간은 여러 영역으로 나누어지고 영역마다 매핑 방법이 달라집니다.보통 사람들은 Linux 커널 공간이 DMA 영역(ZONE_DMA), 일반 영역(ZONE_NORMAL), 고급 메모리 영역(ZONE_HIGHMEM)의 세 가지 영역으로 구성되어 있다고 생각합니다.
커널이 물리 주소에 액세스하는 속도를 향상시키기 위해 가상 주소를 통한 메모리, 커널 공간의 가상화 주소와 물리 메모리 주소는 낮은 주소에서 높은 주소까지 1:1로 대응하는 고정된 매핑 방식을 채택합니다. 아래 그림과 같이
보시다시피 ,이 고정 매핑 방법은 가상 주소와 물리적 메모리 주소를 만듭니다. 주소 간의 관계는 매우 간단해집니다. 즉, 커널 가상 주소와 실제 물리적 주소는 고정 오프셋 PAGE_OFFSET에 의해서만 값이 달라지므로 커널이 가상 주소를 사용할 때 물리적 페이지 프레임에 액세스하려면 가상 주소에서 PAGE_OFFSET만 빼면 실제 물리적 주소를 얻을 수 있으며 이는 페이지 테이블을 사용하는 것보다 훨씬 빠릅니다.
이 방법은 거의 물리 주소를 직접 사용하기 때문에 이런 고정 매핑 기반의 커널 공간을 "물리적 메모리 공간", 줄여서 물리 메모리라고도 합니다. 또한 고정 매핑 방식은 선형 매핑이므로 이 영역을 선형 매핑 영역이라고도 합니다.
물론, 이 경우(컴퓨터의 실제 물리적 메모리가 작은 경우) 커널 고정 매핑 공간은 전체 1GB 커널 공간 중 일부만 차지합니다. 예를 들어 32MB의 실제 물리 메모리로 x86 컴퓨터 시스템을 구성할 때 커널의 고정 매핑 영역은 PAGE_OFFSET~(PAGE_OFFSET+0x02000000)의 32MB 공간입니다. 그렇다면 커널 공간에 남아있는 커널 가상 공간은 어떻게 해야 할까요?
물론 일반적인 가상 공간 관리 방법에 따른 페이지 테이블의 비선형 매핑에는 여전히 물리적 메모리가 사용됩니다. 구체적으로 1GB 커널 공간 전체에서 고정 매핑 영역을 제거한 후 나머지 부분에서 처음의 8MB 격리 영역을 제거하고 나머지는 사용자 공간과 동일하게 매핑되는 일반 가상 메모리 매핑 영역이다. . 이 영역은 가상 주소와 물리 주소 사이에 고정된 매핑 관계가 없을 뿐만 아니라, 커널 함수 vmalloc()을 호출하여 동적 메모리를 획득하므로 이 영역을 아래 그림과 같이 vmalloc 할당 영역이라 부른다. :
실제 물리적 메모리가 32MB로 구성된 x86 컴퓨터 시스템의 경우 vmalloc 할당 영역의 시작 위치는 PAGE_OFFSET+0x02000000+0x00800000입니다. 여기서 설명하겠습니다.여기에 언급된 커널 공간과 물리적 페이지 프레임 간의 고정 매핑은 본질적으로 커널 페이지를 물리적 페이지 프레임에 "예약"하는 것입니다. 이는 이러한 페이지가 이러한 물리적 페이지 프레임을 "점유"한다는 의미는 아닙니다. 즉, 가상 페이지가 실제로 물리적 페이지 프레임에 액세스해야 하는 경우에만 가상 페이지가 물리적 페이지 프레임에 바인딩됩니다. 일반적으로 해당 가상 페이지에서 물리적 페이지 프레임을 사용하지 않는 경우 페이지 프레임은 사용자 공간과 나중에 소개할 커널 kmalloc 할당 영역에서 사용할 수 있습니다.
즉, 실제 물리 메모리가 작은 시스템에서 실제 메모리 크기는 커널 공간의 물리 메모리 영역과 vmalloc 할당 영역의 경계가 됩니다.1GB 커널 공간 전체에 대해 공간 앞부분의 16MB를 DMA 영역, 즉 ZONE_DMA 영역이라고 부르기도 합니다. 물리적 메모리의 DMA 공간을 고정했습니다. 나머지 16MB 공간을 일반 영역, 즉 ZONE_NORMAL이라고 합니다.
커널 공간의 하이엔드 메모리
컴퓨터 기술의 발전으로 컴퓨터의 실제 물리적 메모리가 점점 커지고 있으며, 이로 인해 커널 고정 매핑 영역(선형 영역)이 더 커지고 있습니다. 그리고 더 크다. 분명히 제한이 없으면 실제 물리적 메모리가 1GB에 도달하면 vmalloc 할당 영역(비선형 영역)이 더 이상 존재하지 않게 됩니다. 따라서 이전에 개발된 vmalloc()을 호출하는 커널 코드는 더 이상 사용할 수 없습니다. 물론 초기 커널 코드와 호환되기 위해서는 이는 허용되지 않습니다.
다음 그림은 이 커널 공간이 직면한 상황을 보여줍니다. 분명히,위의 문제가 발생한 이유는 실제 물리적 메모리가 1GB를 초과할 수 있다는 것을 예상하지 못했기 때문에 커널의 경계가 고정되었기 때문입니다. 매핑 영역이 설정되지 않았습니다. 제한을 설정하고 실제 물리적 메모리가 증가함에 따라 증가하도록 합니다.
위 문제를 해결하는 방법은 다음과 같습니다.물리적 메모리 증가에 따라 임의로 증가할 수 없도록 커널 공간의 고정 매핑 영역의 상한을 제한합니다. Linux에서는 커널 매핑 영역의 상한값이 1G보다 작은 상수 high_menory보다 클 수 없다고 규정하고 있으며, 실제 물리적 메모리가 큰 경우에는 3G+high_memory를 물리적 메모리 영역을 결정하는 경계로 사용합니다.
예: x86 시스템의 경우 high_memory 값은 896M이므로 1GB 커널 공간 중 나머지 128MB는 비선형 매핑 영역입니다. 이는 어떠한 경우에도 커널이 초기 코드와 호환될 만큼 충분한 비선형 매핑 영역을 가지며 일반적인 가상 메모리 방식으로 1GB 이상의 실제 물리적 메모리에 액세스할 수 있음을 보장합니다.즉, 하이엔드 메모리의 가장 기본적인 아이디어는 주소 공간의 섹션을 빌려서 임시 주소 매핑을 설정하고 사용 후 해제하는 것입니다. 이 주소 공간을 재활용하여 모든 물리적 메모리에 액세스할 수 있습니다. 컴퓨터에 큰 물리적 메모리가 있는 경우 커널 공간의 개략도는 다음과 같습니다.
전통적으로 Linux에서는 커널 공간의 이 부분을 3G+high_memory~4G-1을 하이엔드 메모리 영역이라고 부릅니다( ZONE_HIGHMEM). 요약하자면: x86 구조의 커널 공간에서 세 가지 유형의 영역(3G에서 계산)은 다음과 같습니다.응용 대상에 따라 다르며, high-end 메모리는 vmalloc 영역, 영구 매핑 영역, 임시 매핑 영역으로 구분됩니다. 커널 공간에서 고급 메모리의 레이아웃은 아래 그림과 같습니다.
vmalloc 매핑 영역은 고급 메모리의 주요 부분입니다. 이 간격의 헤드와 커널 선형 매핑 공간 사이의 간격은 8MB 격리 영역과 끝 부분의 4KB 격리 영역 및 후속 영구 매핑 영역입니다.
vmalloc 매핑 영역의 매핑 방법은 사용자 공간의 매핑 방법과 완전히 동일합니다. 커널은 vmalloc() 함수를 호출하여 이 영역에서 메모리를 얻을 수 있습니다. 이 함수의 기능은 사용자 공간의 malloc()과 동일합니다. 제공되는 메모리 공간은 가상 주소에서 연속적입니다. (물리적 주소는 연속성을 보장하지 않습니다.)
alloc_page()를 통해 고성능 메모리에 해당하는 페이지를 얻은 경우 이에 대한 선형 공간은 어떻게 찾나요?
커널은 영구 커널 매핑 영역인 고급 메모리를 매핑하는 데 사용되는 PKMAP_BASE부터 시작하여 이러한 목적을 위해 특별히 선형 공간을 따로 설정합니다.
영구 커널 매핑 영역에서는 kmap() 함수를 호출하여 물리적 페이지 프레임과 커널 가상 페이지 간의 장기 매핑을 설정할 수 있습니다. 이 공간은 일반적으로 4MB이며 최대 1024개의 페이지 프레임을 매핑할 수 있습니다. 따라서 페이지 프레임의 회전율을 높이려면 kunmap() 함수를 제때에 호출하여 물리적 페이지 프레임을 해제해야 합니다. 더 이상 사용되지 않습니다.
임시 매핑 영역은 고정 매핑 영역, 예약 영역이라고도 합니다. 이 영역은 주로 다중 프로세서 시스템에서 사용됩니다. 이 영역에서 얻은 메모리 공간은 보호되지 않으므로 얻은 메모리를 제때에 사용해야 합니다. 그렇지 않으면 새 요청이 있으면 페이지 프레임의 내용을 덮어쓰게 됩니다. . 이므로 이 영역을 임시 매핑 영역이라고 합니다.
하이엔드 메모리 영역에 관한 아주 좋은 기사: Linux 사용자 공간과 커널 공간-하이엔드 메모리에 대한 자세한 설명.
커널 메모리 할당 수정자 gfp
커널 메모리 요청 함수에서 요청에 대해 필요한 설명을 제공하기 위해 Linux에서는 다양한 메모리 할당 수정자 gfp를 정의합니다. 이는 동작 수정자, 영역 수정자 및 유형 수정자입니다.
메모리 할당 함수의 동작 수정자는 커널이 메모리를 할당하는 방법을 설명합니다. 주요 동작 수정자는 다음과 같습니다.
수정자 | 설명 |
__GFP_WAIT | 할당자는 잠자기 가능 |
__GFP_HIGH | 할당자는 긴급 상황에 접근할 수 있습니다. 이벤트 버퍼 풀 g___gfp_io allocator는 디스크를 시작할 수 있습니다 io |
__gfp_fs | 할당자는 파일 시스템을 시작할 수 있습니다. 캐시 |
__GFP_NOWARN | 할당자가 경고를 발행하지 않음 |
__GFP_REPEAT | 할당 실패 시 재할당 |
__GFP_NOFAILT | 성공할 때까지 할당 실패 시 재할당 |
__GFP_NORETRY | 할당이 실패하면 더 이상 재할당이 발생하지 않습니다. |
지역 수정자 | |
지역 수정자는 할당해야 하는 커널 공간 메모리 영역을 나타냅니다. 기본적으로 메모리 할당자는 커널 공간의 ZONE_NORMAL에서 시작하여 점차적으로 메모리 요청자에게 메모리 영역을 할당합니다. 사용자가 특별히 ZONE_DMA 또는 ZONE_HOGNMEM에서 메모리를 가져와야 하는 경우 메모리 요청자는 메모리에서 다음 두 영역을 사용해야 합니다. 요청 함수. 수정자 설명: |
__GFP_DMA
ZONE_HIGHMEM 영역에서 메모리 할당 | ||||||||||
고사양 메모리(3G+high_memory~4G) ZONE_HIGHMEM비선형 매핑 영역 | 임시 매핑 영역||
저사양 메모리(3G~3G+high_memory-1)선형 매핑 영역(고정 매핑 영역) | ZONE_NORMAL||
페이지 디렉토리 --> 중간 페이지 디렉토리 --> 페이지 테이블 |
Linux 비디오 튜토리얼"
위 내용은 Linux 드라이버는 어떤 공간에서 실행되나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!