>  기사  >  운영 및 유지보수  >  Linux 드라이버는 어떤 공간에서 실행되나요?

Linux 드라이버는 어떤 공간에서 실행되나요?

青灯夜游
青灯夜游원래의
2022-11-10 20:02:391876검색

Linux 드라이버는 "커널" 공간에서 실행됩니다. 일반적으로 드라이버는 kmalloc()를 호출하여 데이터 구조에 대한 메모리를 할당하고, vmalloc()를 호출하여 활성 스왑 영역에 대한 데이터 구조를 할당하거나, 일부 I/O 드라이버에 대한 버퍼를 할당하거나, kmalloc 및 vmalloc이 커널 메모리를 할당할 공간을 할당합니다.

Linux 드라이버는 어떤 공간에서 실행되나요?

이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.

Linux 드라이버는 "커널" 공간에서 실행됩니다.

일반적으로 작성된 마이크로 컨트롤러 프로그램의 경우 애플리케이션과 드라이버가 혼합되는 경우가 많습니다. 일정 수준의 능력을 갖춘 마이크로 컨트롤러 프로그래머는 애플리케이션과 드라이버의 계층화를 실현할 수 있습니다. Linux 시스템에서는 애플리케이션과 드라이버가 강제로 계층화되었습니다.

마이크로 컨트롤러 프로그램에서 애플리케이션은 기본 레지스터를 직접 작동할 수 있습니다. 그러나 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 크기의 커널 공간입니다.

시스템에서 여러 프로그램이 실행 중인 경우 여러 사용자 공간과 커널 공간의 관계는 다음과 같이 표현할 수 있습니다.

Linux 드라이버는 어떤 공간에서 실행되나요?

그림과 같이 프로그램 1, 2...n이 커널 공간을 공유합니다. . 물론 여기서 공유는 시간 공유를 의미합니다. 단일 코어 프로세서 시스템의 경우 언제든지 하나의 프로그램만 실행할 수 있기 때문입니다.

커널 공간의 전체 레이아웃

리눅스의 개발 과정에서 하드웨어 장비의 업데이트와 기술 수준의 향상에 따라 커널 공간 레이아웃의 개발도 지속적인 패치의 한 방법입니다. 그 결과 커널 공간은 여러 영역으로 나누어지고 영역마다 매핑 방법이 달라집니다.

보통 사람들은 Linux 커널 공간이 DMA 영역(ZONE_DMA), 일반 영역(ZONE_NORMAL), 고급 메모리 영역(ZONE_HIGHMEM)의 세 가지 영역으로 구성되어 있다고 생각합니다.

실제 물리 메모리가 작을 때 커널 공간을 직접 매핑

초기 컴퓨터에 구성된 실제 물리 메모리는 대개 몇 MB에 불과하므로

커널이 물리 주소에 액세스하는 속도를 향상시키기 위해 가상 주소를 통한 메모리, 커널 공간의 가상화 주소와 물리 메모리 주소는 낮은 주소에서 높은 주소까지 1:1로 대응하는 고정된 매핑 방식을 채택합니다. 아래 그림과 같이

Linux 드라이버는 어떤 공간에서 실행되나요?

보시다시피 ,

이 고정 매핑 방법은 가상 주소와 물리적 메모리 주소를 만듭니다. 주소 간의 관계는 매우 간단해집니다. 즉, 커널 가상 주소와 실제 물리적 주소는 고정 오프셋 PAGE_OFFSET에 의해서만 값이 달라지므로 커널이 가상 주소를 사용할 때 물리적 페이지 프레임에 액세스하려면 가상 주소에서 PAGE_OFFSET만 빼면 실제 물리적 주소를 얻을 수 있으며 이는 페이지 테이블을 사용하는 것보다 훨씬 빠릅니다.

이 방법은 거의 물리 주소를 직접 사용하기 때문에 이런 고정 매핑 기반의 커널 공간을 "물리적 메모리 공간", 줄여서 물리 메모리라고도 합니다. 또한 고정 매핑 방식은 선형 매핑이므로 이 영역을 선형 매핑 영역이라고도 합니다.

물론, 이 경우(컴퓨터의 실제 물리적 메모리가 작은 경우) 커널 고정 매핑 공간은 전체 1GB 커널 공간 중 일부만 차지합니다. 예를 들어 32MB의 실제 물리 메모리로 x86 컴퓨터 시스템을 구성할 때 커널의 고정 매핑 영역은 PAGE_OFFSET~(PAGE_OFFSET+0x02000000)의 32MB 공간입니다. 그렇다면 커널 공간에 남아있는 커널 가상 공간은 어떻게 해야 할까요?

물론 일반적인 가상 공간 관리 방법에 따른 페이지 테이블의 비선형 매핑에는 여전히 물리적 메모리가 사용됩니다. 구체적으로 1GB 커널 공간 전체에서 고정 매핑 영역을 제거한 후 나머지 부분에서 처음의 8MB 격리 영역을 제거하고 나머지는 사용자 공간과 동일하게 매핑되는 일반 가상 메모리 매핑 영역이다. . 이 영역은 가상 주소와 물리 주소 사이에 고정된 매핑 관계가 없을 뿐만 아니라, 커널 함수 vmalloc()을 호출하여 동적 메모리를 획득하므로 이 영역을 아래 그림과 같이 vmalloc 할당 영역이라 부른다. :

Linux 드라이버는 어떤 공간에서 실행되나요?

실제 물리적 메모리가 32MB로 구성된 x86 컴퓨터 시스템의 경우 vmalloc 할당 영역의 시작 위치는 PAGE_OFFSET+0x02000000+0x00800000입니다.

여기서 설명하겠습니다.

여기에 언급된 커널 공간과 물리적 페이지 프레임 간의 고정 매핑은 본질적으로 커널 페이지를 물리적 페이지 프레임에 "예약"하는 것입니다. 이는 이러한 페이지가 이러한 물리적 페이지 프레임을 "점유"한다는 의미는 아닙니다. 즉, 가상 페이지가 실제로 물리적 페이지 프레임에 액세스해야 하는 경우에만 가상 페이지가 물리적 페이지 프레임에 바인딩됩니다. 일반적으로 해당 가상 페이지에서 물리적 페이지 프레임을 사용하지 않는 경우 페이지 프레임은 사용자 공간과 나중에 소개할 커널 kmalloc 할당 영역에서 사용할 수 있습니다.

즉, 실제 물리 메모리가 작은 시스템에서 실제 메모리 크기는 커널 공간의 물리 메모리 영역과 vmalloc 할당 영역의 경계가 됩니다.

ZONE_DMA 영역과 ZONE_NORMAL 영역

1GB 커널 공간 전체에 대해 공간 앞부분의 16MB를 DMA 영역, 즉 ZONE_DMA 영역이라고 부르기도 합니다. 물리적 메모리의 DMA 공간을 고정했습니다. 나머지 16MB 공간을 일반 영역, 즉 ZONE_NORMAL이라고 합니다.

커널 공간의 하이엔드 메모리

컴퓨터 기술의 발전으로 컴퓨터의 실제 물리적 메모리가 점점 커지고 있으며, 이로 인해 커널 고정 매핑 영역(선형 영역)이 더 커지고 있습니다. 그리고 더 크다. 분명히 제한이 없으면 실제 물리적 메모리가 1GB에 도달하면 vmalloc 할당 영역(비선형 영역)이 더 이상 존재하지 않게 됩니다. 따라서 이전에 개발된 vmalloc()을 호출하는 커널 코드는 더 이상 사용할 수 없습니다. 물론 초기 커널 코드와 호환되기 위해서는 이는 허용되지 않습니다.

다음 그림은 이 커널 공간이 직면한 상황을 보여줍니다.

Linux 드라이버는 어떤 공간에서 실행되나요?

분명히,

위의 문제가 발생한 이유는 실제 물리적 메모리가 1GB를 초과할 수 있다는 것을 예상하지 못했기 때문에 커널의 경계가 고정되었기 때문입니다. 매핑 영역이 설정되지 않았습니다. 제한을 설정하고 실제 물리적 메모리가 증가함에 따라 증가하도록 합니다.

위 문제를 해결하는 방법은 다음과 같습니다.

물리적 메모리 증가에 따라 임의로 증가할 수 없도록 커널 공간의 고정 매핑 영역의 상한을 제한합니다. Linux에서는 커널 매핑 영역의 상한값이 1G보다 작은 상수 high_menory보다 클 수 없다고 규정하고 있으며, 실제 물리적 메모리가 큰 경우에는 3G+high_memory를 물리적 메모리 영역을 결정하는 경계로 사용합니다.

예: x86 시스템의 경우 high_memory 값은 896M이므로 1GB 커널 공간 중 나머지 128MB는 비선형 매핑 영역입니다. 이는 어떠한 경우에도 커널이 초기 코드와 호환될 만큼 충분한 비선형 매핑 영역을 가지며 일반적인 가상 메모리 방식으로 1GB 이상의 실제 물리적 메모리에 액세스할 수 있음을 보장합니다.

즉, 하이엔드 메모리의 가장 기본적인 아이디어는 주소 공간의 섹션을 빌려서 임시 주소 매핑을 설정하고 사용 후 해제하는 것입니다. 이 주소 공간을 재활용하여 모든 물리적 메모리에 액세스할 수 있습니다. 컴퓨터에 큰 물리적 메모리가 있는 경우 커널 공간의 개략도는 다음과 같습니다.

Linux 드라이버는 어떤 공간에서 실행되나요?

전통적으로 Linux에서는 커널 공간의 이 부분을 3G+high_memory~4G-1을 하이엔드 메모리 영역이라고 부릅니다( ZONE_HIGHMEM).

요약하자면: x86 구조의 커널 공간에서 세 가지 유형의 영역(3G에서 계산)은 다음과 같습니다.

  • ZONE_DMA: 커널 공간 시작 16MB
  • ZONE_NORMAL: 커널 공간 16MB~896MB(고정 매핑)
  • ZONE_HIGHMEM: 커널 공간 896MB ~ 끝(1G)

응용 대상에 따라 다르며, high-end 메모리는 vmalloc 영역, 영구 매핑 영역, 임시 매핑 영역으로 구분됩니다. 커널 공간에서 고급 메모리의 레이아웃은 아래 그림과 같습니다.

Linux 드라이버는 어떤 공간에서 실행되나요?

vmalloc 매핑 영역

vmalloc 매핑 영역은 고급 메모리의 주요 부분입니다. 이 간격의 헤드와 커널 선형 매핑 공간 사이의 간격은 8MB 격리 영역과 끝 부분의 4KB 격리 영역 및 후속 영구 매핑 영역입니다.

vmalloc 매핑 영역의 매핑 방법은 사용자 공간의 매핑 방법과 완전히 동일합니다. 커널은 vmalloc() 함수를 호출하여 이 영역에서 메모리를 얻을 수 있습니다. 이 함수의 기능은 사용자 공간의 malloc()과 동일합니다. 제공되는 메모리 공간은 가상 주소에서 연속적입니다. (물리적 주소는 연속성을 보장하지 않습니다.)

영구 커널 매핑 영역

alloc_page()를 통해 고성능 메모리에 해당하는 페이지를 얻은 경우 이에 대한 선형 공간은 어떻게 찾나요?

커널은 영구 커널 매핑 영역인 고급 메모리를 매핑하는 데 사용되는 PKMAP_BASE부터 시작하여 이러한 목적을 위해 특별히 선형 공간을 따로 설정합니다.

영구 커널 매핑 영역에서는 kmap() 함수를 호출하여 물리적 페이지 프레임과 커널 가상 페이지 간의 장기 매핑을 설정할 수 있습니다. 이 공간은 일반적으로 4MB이며 최대 1024개의 페이지 프레임을 매핑할 수 있습니다. 따라서 페이지 프레임의 회전율을 높이려면 kunmap() 함수를 제때에 호출하여 물리적 페이지 프레임을 해제해야 합니다. 더 이상 사용되지 않습니다.

임시 매핑 영역

임시 매핑 영역은 고정 매핑 영역, 예약 영역이라고도 합니다. 이 영역은 주로 다중 프로세서 시스템에서 사용됩니다. 이 영역에서 얻은 메모리 공간은 보호되지 않으므로 얻은 메모리를 제때에 사용해야 합니다. 그렇지 않으면 새 요청이 있으면 페이지 프레임의 내용을 덮어쓰게 됩니다. . 이므로 이 영역을 임시 매핑 영역이라고 합니다.

하이엔드 메모리 영역에 관한 아주 좋은 기사: Linux 사용자 공간과 커널 공간-하이엔드 메모리에 대한 자세한 설명.

커널 메모리 할당 수정자 gfp

커널 메모리 요청 함수에서 요청에 대해 필요한 설명을 제공하기 위해 Linux에서는 다양한 메모리 할당 수정자 gfp를 정의합니다. 이는 동작 수정자, 영역 수정자 및 유형 수정자입니다.

동작 수정자

메모리 할당 함수의 동작 수정자는 커널이 메모리를 할당하는 방법을 설명합니다. 주요 동작 수정자는 다음과 같습니다.

지역 수정자 Linux의 주요 커널 메모리 할당 영역 수정자
Linux용 기본 커널 메모리 할당 동작 수정자
수정자 설명
__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_DMA 영역에서 메모리 할당 __GFP_ HIGHMEM ZONE_HIGHMEM 영역에서 메모리 할당

类型修饰符

类型修饰符实质上是上述所述修饰符的联合应用。也就是:将上述的某些行为修饰符和区修饰符,用“|”进行连接并另外取名的修饰符。这里就不多介绍了。

内核常用内存分配及地址映射函数

函数vmalloc()

函数vmalloc()在vmalloc分配区分配内存,可获得虚拟地址连续,但并不保证其物理页框连续的较大内存。与物理空间的内存分配函数malloc()有所区别,vmalloc()分配的物理页不会被交换出去。函数vmalloc()的原型如下:

void *vmalloc(unsigned long size)
{
       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
{
	return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
}

其中,参数size为所请求内存的大小,返回值为所获得内存虚拟地址指针。

与vmalloc()配套的释放函数如下:

void vfree(const void *addr)
{
	kfree(addr);
}

其中,参数addr为待释放内存指针。

函数kmalloc()

kmalloc()是内核另一个常用的内核分配函数,它可以分配一段未清零的连续物理内存页,返回值为直接映射地址。由kmalloc()可分配的内存最大不能超过32页。其优点是分配速度快,缺点是不能分配大于128KB的内存页(出于跨平台考虑)。

在linux/slab.h文件中,该函数的原型声明如下:

static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
	struct kmem_cache *cachep;
	void *ret;

	if (__builtin_constant_p(size)) {
		int i = 0;

		if (!size)
			return ZERO_SIZE_PTR;

#define CACHE(x) \
		if (size <= x) \
			goto found; \
		else \
			i++;
#include <linux/kmalloc_sizes.h>
#undef CACHE
		return NULL;
found:
#ifdef CONFIG_ZONE_DMA
		if (flags & GFP_DMA)
			cachep = malloc_sizes[i].cs_dmacachep;
		else
#endif
			cachep = malloc_sizes[i].cs_cachep;

		ret = kmem_cache_alloc_notrace(cachep, flags);

		trace_kmalloc(_THIS_IP_, ret,
			      size, slab_buffer_size(cachep), flags);

		return ret;
	}
	return __kmalloc(size, flags);
}

其中,参数size为以字节为单位表示的所申请空间的大小;参数flags决定了所分配的内存适合什么场合。

与函数kmalloc()对应的释放函数如下:

void kfree(const void *objp)
{
	struct kmem_cache *c;
	unsigned long flags;

	trace_kfree(_RET_IP_, objp);

	if (unlikely(ZERO_OR_NULL_PTR(objp)))
		return;
	local_irq_save(flags);
	kfree_debugcheck(objp);
	c = virt_to_cache(objp);
	debug_check_no_locks_freed(objp, obj_size(c));
	debug_check_no_obj_freed(objp, obj_size(c));
	__cache_free(c, (void *)objp);
	local_irq_restore(flags);
}

小结一下,kmalloc、vmalloc、malloc的区别:

  • kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存;
  • kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续,malloc不保证任何东西;
  • kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相对较大;
  • vmalloc比kmalloc要慢。

也就是说:kmalloc、vmalloc这两个函数所分配的内存都处于内核空间,即从3GB~4GB;但位置不同,kmalloc()分配的内存处于3GB~high_memory(ZONE_DMA、ZONE_NORMAL)之间,而vmalloc()分配的内存在VMALLOC_START~4GB(ZONE_HIGHMEM)之间,也就是非连续内存区。一般情况下在驱动程序中都是调用kmalloc()来给数据结构分配内存,而vmalloc()用在为活动的交换区分配数据结构,为某些I/O驱动程序分配缓冲区,或为模块分配空间。

Linux 드라이버는 어떤 공간에서 실행되나요?

可参考文章:Kmalloc和Vmalloc的区别

函数alloc_pages()

与上述在虚拟空间分配内存的函数不同,alloc_pages()是在物理内存空间分配物理页框的函数,其原型如下:

static inline struct page * alloc_pages(gfp_t gfp_mask, unsigned int order)
{
	if (unlikely(order >= MAX_ORDER))
		return NULL;

	return alloc_pages_current(gfp_mask, order);
}

其中,参数order表示所分配页框的数目,该数目为2^order。order的最大值由include/Linux/Mmzone.h文件中的宏MAX_ORDER决定。参数gfp_mask为说明内存页框分配方式及使用场合。

函数返回值为页框块的第一个页框page结构的地址。

调用下列函数可以获得页框的虚拟地址:

void *page_address(struct page *page)
{
	unsigned long flags;
	void *ret;
	struct page_address_slot *pas;
 
	if (!PageHighMem(page))
		return lowmem_page_address(page);
 
	pas = page_slot(page);
	ret = NULL;
	spin_lock_irqsave(&pas->lock, flags);
	if (!list_empty(&pas->lh)) {
		struct page_address_map *pam;
 
		list_for_each_entry(pam, &pas->lh, list) {
			if (pam->page == page) {
				ret = pam->virtual;
				goto done;
			}
		}
	}
done:
	spin_unlock_irqrestore(&pas->lock, flags);
	return ret;
}

使用函数alloc_pages()获得的内存应该使用下面的函数释放:

void __free_pages(struct page *page, unsigned int order)
{
	if (put_page_testzero(page)) {
		if (order == 0)
			free_hot_page(page);
		else
			__free_pages_ok(page, order);
	}
}

函数kmap()

kmap()是一个映射函数,它可以将一个物理页框映射到内核空间的可持久映射区。这种映射类似于内核ZONE_NORMAL的固定映射,但虚拟地址与物理地址的偏移不一定是PAGE_OFFSET。由于内核可持久映射区的容量有限(总共只有4MB),因此当内存使用完毕后,应该立即释放。

函数kmap()的函数原型如下:

void *kmap(struct page *page)
{
	might_sleep();
	if (!PageHighMem(page))
		return page_address(page);
	return kmap_high(page);
}

小结

由于CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间,实际内存容量小于4G),逻辑空间也只能描述4G的线性地址空间。

为了合理的利用逻辑4G空间,Linux采用了3:1的策略,即内核占用1G的线性地址空间,用户占用3G的线性地址空间。所以用户进程的地址范围从0~3G,内核地址范围从3G~4G,也就是说,内核空间只有1G的逻辑线性地址空间。

Linux 물리적 메모리 공간이 1G 미만인 경우 커널은 일반적으로 물리적 메모리를 주소 공간에 선형적으로 매핑합니다. 즉, 일대일 매핑을 통해 액세스 속도를 향상할 수 있습니다. 그러나 Linux의 물리적 메모리가 1G를 초과하면 1G의 메모리만 매핑할 수 있고 나머지 물리적 메모리는 커널에서 관리할 수 없기 때문에 선형 액세스 메커니즘이 충분하지 않습니다. 선형 영역과 비선형 영역의 두 부분으로 나누어집니다. 선형 영역은 최대 896M로 규정되며 나머지 128M은 비선형 영역입니다. 따라서 선형 영역에 매핑된 물리적 메모리는 low-end 메모리가 되고, 나머지 물리적 메모리는 high-end 메모리라고 합니다. 선형 영역과 달리 비선형 영역은 미리 메모리 매핑되지 않지만 사용 시 동적으로 매핑됩니다.

저사양 메모리는 두 부분으로 나뉩니다. ZONE_DMA: 커널 공간 시작 부분의 16MB, ZONE_NORMAL: 커널 공간의 16MB~896MB(고정 매핑). 나머지는 고급 메모리입니다: ZONE_HIGHMEM: 커널 공간 896MB ~ 끝(1G).

다양한 애플리케이션 목표에 따라 고급 메모리는 vmalloc 영역, 영구 매핑 영역 및 임시 매핑 영역의 세 부분으로 나뉩니다. vmalloc 영역은 vmalloc() 함수를 사용하여 할당됩니다. 영구 매핑 영역은 해당 페이지를 얻기 위해 allc_pages()를 사용하고 kmap() 함수를 사용하여 직접 매핑됩니다. 임시 매핑 영역은 일반적으로 특별한 요구에 사용됩니다.

사용자 공간 및 커널 공간커널 공간(3G~4G)임시 매핑 영역 Yes 영구 매핑 영역vmalloc 영역ZONE_NORMALZONE_DMA 사용자 공간(0~3G-1) 페이지 디렉토리 --> 중간 페이지 디렉토리 --> 페이지 테이블
고사양 메모리(3G+high_memory~4G) ZONE_HIGHMEM

비선형 매핑 영역

저사양 메모리(3G~3G+high_memory-1)

선형 매핑 영역(고정 매핑 영역)

관련 권장사항: "

Linux 비디오 튜토리얼"

위 내용은 Linux 드라이버는 어떤 공간에서 실행되나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.