溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

linux驅(qū)動程序運行空間是什么

發(fā)布時間:2022-11-11 09:47:11 來源:億速云 閱讀:99 作者:iii 欄目:建站服務(wù)器

這篇文章主要介紹“l(fā)inux驅(qū)動程序運行空間是什么”,在日常操作中,相信很多人在linux驅(qū)動程序運行空間是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”linux驅(qū)動程序運行空間是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

linux驅(qū)動程序運行在“內(nèi)核”空間。一般情況下驅(qū)動程序中都是調(diào)用kmalloc()來給數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,調(diào)用vmalloc()為活動的交換區(qū)分配數(shù)據(jù)結(jié)構(gòu),為某些I/O驅(qū)動程序分配緩沖區(qū),或為模塊分配空間;kmalloc和vmalloc分配的是內(nèi)核的內(nèi)存。

linux驅(qū)動程序運行在“內(nèi)核”空間。

對于一般編寫的單片機程序來說應(yīng)用程序和驅(qū)動程序往往是雜糅的,擁有一定能力水平的單片機程序編程人員可以實現(xiàn)應(yīng)用和驅(qū)動的分層。而在Linux系統(tǒng)中已經(jīng)強制將應(yīng)用和驅(qū)動進(jìn)行了分層。

在單片機程序中,應(yīng)用可以直接操作底層的寄存器。而在Linux系統(tǒng)中卻禁止這樣的行為,舉個例子:Linux應(yīng)用的編寫人員故意在應(yīng)用中調(diào)用了驅(qū)動中關(guān)于電源管理的驅(qū)動,關(guān)閉了系統(tǒng),那不就得不償失了?

具體的Linux應(yīng)用程序?qū)︱?qū)動的調(diào)用如圖所示:

linux驅(qū)動程序運行空間是什么

應(yīng)用程序運行在用戶空間,驅(qū)動程序運行在內(nèi)核空間。處于用戶空間應(yīng)用程序如果想要實現(xiàn)對內(nèi)核的操作,必須經(jīng)過一種"系統(tǒng)調(diào)用"的方法,實現(xiàn)從用戶空間進(jìn)入內(nèi)核空間,實現(xiàn)對底層的操作。

Linux中的內(nèi)核空間

內(nèi)核也是程序,也應(yīng)該具有自己的虛存空間,但是作為一種為用戶程序服務(wù)的程序,內(nèi)核空間有它自己的特點。

內(nèi)核空間與用戶空間的關(guān)系

在一個32位系統(tǒng)中,一個程序的虛擬空間最大可以是4GB,那么最直接的做法就是,把內(nèi)核也看作是一個程序,使它和其他程序一樣也具有4GB空間。但是這種做法會使系統(tǒng)不斷的切換用戶程序的頁表和內(nèi)核頁表,以致影響計算機的效率。解決這個問題的最好做法就是把4GB空間分成兩個部分:一部分為用戶空間,另一部分為內(nèi)核空間,這樣就可以保證內(nèi)核空間固定不變,而當(dāng)程序切換時,改變的僅是程序的頁表。這種做法的唯一缺點便是內(nèi)核空間和用戶空間均變小了。

例如:在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的虛擬內(nèi)存空間分成了兩部分:地址0~3G-1這段低地址空間為用戶空間,大小為3GB;地址3GB~4GB-1這段高地址空間為內(nèi)核空間,大小為1GB。

當(dāng)系統(tǒng)中運行多個程序時,多個用戶空間與內(nèi)核空間的關(guān)系可以表示如下圖:

linux驅(qū)動程序運行空間是什么

如圖中所示,程序1、2……n共享內(nèi)核空間。當(dāng)然,這里的共享指得是分時共享,因為在任何時刻,對于單核處理器系統(tǒng)來說,只能有一個程序在運行。

內(nèi)核空間的總體布局

Linux在發(fā)展過程中,隨著硬件設(shè)備的更新和技術(shù)水平的提高,其內(nèi)核空間布局的發(fā)展也是一種不斷打補丁的方式。這樣的后果就是使得內(nèi)核空間被分成不同的幾個區(qū)域,而且在不同的區(qū)域具有不同的映射方式。通常,人們認(rèn)為Linux內(nèi)核空間有三個區(qū)域,即DMA區(qū)(ZONE_DMA)、普通區(qū)(ZONE_NORMAL)和高端內(nèi)存區(qū)(ZONE_HIGHMEM)。

實際物理內(nèi)存較小時內(nèi)核空間的直接映射

早期計算機實際配置的物理內(nèi)存通常只有幾MB,所以為了提高內(nèi)核通過虛擬地址訪問物理地址內(nèi)存的速度,內(nèi)核空間的虛擬地址與物理內(nèi)存地址采用了一種從低地址向高地址依次一一對應(yīng)的固定映射方式,如下圖所示:

linux驅(qū)動程序運行空間是什么

可以看到,這種固定映射方式使得虛擬地址與物理地址的關(guān)系變得很簡單,即內(nèi)核虛擬地址與實際物理地址只在數(shù)值上相差一個固定的偏移量PAGE_OFFSET,所以當(dāng)內(nèi)核使用虛擬地址訪問物理頁框時,只需在虛擬地址上減去PAGE_OFFSET即可得到實際物理地址,比使用頁表的方式要快得多!

由于這種做法幾乎就是直接使用物理地址,所以這種按固定映射方式的內(nèi)核空間也就叫做“物理內(nèi)存空間”,簡稱物理內(nèi)存。另外,由于固定映射方式是一種線性映射,所以這個區(qū)域也叫做線性映射區(qū)。

當(dāng)然,這種情況下(計算機實際物理內(nèi)存較小時),內(nèi)核固定映射空間僅占整個1GB內(nèi)核空間的一部分。例如:在配置32MB實際物理內(nèi)存的x86計算機系統(tǒng)時,內(nèi)核的固定映射區(qū)便是PAGE_OFFSET~(PAGE_OFFSET+0x02000000)這個32MB空間。那么內(nèi)核空間剩余的內(nèi)核虛擬空間怎么辦呢?

當(dāng)然還是按照普通虛擬空間的管理方式,以頁表的非線性映射方式使用物理內(nèi)存。具體來說,在整個1GB內(nèi)核空間中去除固定映射區(qū),然后在剩余部分中再去除其開頭部分的一個8MB隔離區(qū),余下的就是映射方式與用戶空間相同的普通虛擬內(nèi)存映射區(qū)。在這個區(qū),虛擬地址和物理地址不僅不存在固定映射關(guān)系,而且通過調(diào)用內(nèi)核函數(shù)vmalloc()獲得動態(tài)內(nèi)存,故這個區(qū)就被稱為vmalloc分配區(qū),如下圖所示:

linux驅(qū)動程序運行空間是什么

對于配置32MB實際物理內(nèi)存的x86計算機系統(tǒng)來說,vmalloc分配區(qū)的起始位置為PAGE_OFFSET+0x02000000+0x00800000。

這里說明一下:這里說的內(nèi)核空間與物理頁框的固定映射,實質(zhì)上是內(nèi)核頁對物理頁框的一種“預(yù)定”,并不是說這些頁就“霸占”了這些物理頁框。即只有當(dāng)虛擬頁真正需要訪問物理頁框時,虛擬頁才與物理頁框綁定。而平時,當(dāng)某個物理頁框不被與它對應(yīng)的虛擬頁所使用時,該頁框完全可以被用戶空間以及后面所介紹的內(nèi)核kmalloc分配區(qū)使用。

總之,在實際物理內(nèi)存較小的系統(tǒng)中,實際內(nèi)存的大小就是內(nèi)核空間的物理內(nèi)存區(qū)與vmalloc分配區(qū)的邊界。

ZONE_DMA區(qū)與ZONE_NORMAL區(qū)

對于整個1GB的內(nèi)核空間,人們還把該空間頭部的16MB叫做DMA區(qū),即ZONE_DMA區(qū),因為以往硬件將DMA空間固定在了物理內(nèi)存的低16MB空間;其余區(qū)則叫做普通區(qū),即ZONE_NORMAL。

內(nèi)核空間的高端內(nèi)存

隨著計算機技術(shù)的發(fā)展,計算機的實際物理內(nèi)存越來越大,從而使得內(nèi)核固定映射區(qū)(線性區(qū))也越來越大。顯然,如果不加以限制,當(dāng)實際物理內(nèi)存達(dá)到1GB時,vmalloc分配區(qū)(非線性區(qū))將不復(fù)存在。于是以前開發(fā)的、調(diào)用了vmalloc()的內(nèi)核代碼也就不再可用,顯然為了兼容早期的內(nèi)核代碼,這是不能允許的。

下圖就表示了這種內(nèi)核空間所面臨的局面:

linux驅(qū)動程序運行空間是什么

顯然,出現(xiàn)上述問題的原因就是沒有預(yù)料到實際物理內(nèi)存可以超過1GB,因而沒有為內(nèi)核固定映射區(qū)的邊界設(shè)定限制,而任由其隨著實際物理內(nèi)存的增大而增大。

解決上述問題的方法就是:對內(nèi)核空間固定映射區(qū)的上限加以限制,使之不能隨著物理內(nèi)存的增加而任意增加。Linux規(guī)定,內(nèi)核映射區(qū)的上邊界的值最大不能大于一個小于1G的常數(shù)high_menory,當(dāng)實際物理內(nèi)存較大時,以3G+high_memory為邊界來確定物理內(nèi)存區(qū)。

例如:對于x86系統(tǒng),high_memory的值為896M,于是1GB內(nèi)核空間余下的128MB為非線性映射區(qū)。這樣就確保在任何情況下,內(nèi)核都有足夠的非線性映射區(qū)以兼容早期代碼并可以按普通虛存方式訪問實際物理內(nèi)存的1GB以上的空間。

也就是說,高端內(nèi)存的最基本思想:借一段地址空間,建立臨時地址映射,用完后釋放,達(dá)到這段地址空間可以循環(huán)使用,訪問所有物理內(nèi)存。當(dāng)計算機是物理內(nèi)存較大時,內(nèi)核空間的示意圖如下:

linux驅(qū)動程序運行空間是什么

習(xí)慣上,Linux把內(nèi)核空間3G+high_memory~4G-1的這個部分叫做高端內(nèi)存區(qū)(ZONE_HIGHMEM)。

總結(jié)一下:在x86結(jié)構(gòu)的內(nèi)核空間,三種類型的區(qū)域(從3G開始計算)如下:

  • ZONE_DMA:內(nèi)核空間開始的16MB

  • ZONE_NORMAL:內(nèi)核空間16MB~896MB(固定映射)

  • ZONE_HIGHMEM :內(nèi)核空間896MB ~ 結(jié)束(1G)

根據(jù)應(yīng)用目標(biāo)不同,高端內(nèi)存區(qū)分vmalloc區(qū)、可持久映射區(qū)和臨時映射區(qū)。內(nèi)核空間中高端內(nèi)存的布局如下圖所示:

linux驅(qū)動程序運行空間是什么

vmalloc映射區(qū)

vmalloc映射區(qū)時高端內(nèi)存的主要部分,該區(qū)間的頭部與內(nèi)核線性映射空間之間有一個8MB的隔離區(qū),尾部與后續(xù)的可持久映射區(qū)有一個4KB的隔離區(qū)。

vmalloc映射區(qū)的映射方式與用戶空間完全相同,內(nèi)核可以通過調(diào)用函數(shù)vmalloc()在這個區(qū)域獲得內(nèi)存。這個函數(shù)的功能相當(dāng)于用戶空間的malloc(),所提供的內(nèi)存空間在虛擬地址上連續(xù)(注意,不保證物理地址連續(xù))。

可持久內(nèi)核映射區(qū)

如果是通過 alloc_page() 獲得了高端內(nèi)存對應(yīng)的 page,如何給它找個線性空間?

內(nèi)核專門為此留出一塊線性空間,從PKMAP_BASE開始,用于映射高端內(nèi)存,就是可持久內(nèi)核映射區(qū)。

在可持久內(nèi)核映射區(qū),可通過調(diào)用函數(shù)kmap()在物理頁框與內(nèi)核虛擬頁之間建立長期映射。這個空間通常為4MB,最多能映射1024個頁框,數(shù)量較為稀少,所以為了加強頁框的周轉(zhuǎn),應(yīng)及時調(diào)用函數(shù)kunmap()將不再使用的物理頁框釋放。

臨時映射區(qū)

臨時映射區(qū)也叫固定映射區(qū)和保留區(qū)。該區(qū)主要應(yīng)用在多處理器系統(tǒng)中,因為在這個區(qū)域所獲得的內(nèi)存空間沒有所保護,故所獲得的內(nèi)存必須及時使用;否則一旦有新的請求,該頁框上的內(nèi)容就會被覆蓋,所以這個區(qū)域叫做臨時映射區(qū)。

關(guān)于高端內(nèi)存區(qū)一篇很不錯的文章:linux 用戶空間與內(nèi)核空間——高端內(nèi)存詳解。

內(nèi)核內(nèi)存分配修飾符gfp

為了在內(nèi)核內(nèi)存請求函數(shù)對請求進(jìn)行必要的說明,Linux定義了多種內(nèi)存分配修飾符gfp。它們是行為修飾符、區(qū)修飾符、類型修飾符。

行為修飾符

在內(nèi)存分配函數(shù)中的行為修飾符說明內(nèi)核應(yīng)當(dāng)如何分配內(nèi)存。主要行為修飾符如下:

Linux的主要內(nèi)核內(nèi)存分配行為修飾符
修飾符說明
__GFP_WAIT分配器可以休眠
__GFP_HIGH分配器可以訪問緊急事件緩沖池
__GFP_IO分配器可以啟動磁盤IO
__GFP_FS分配器可以啟動文件系統(tǒng)IO
__GFP_COLD分配器應(yīng)該使用高速緩沖中快要淘汰的頁框
__GFP_NOWARN分配器不發(fā)出警告
__GFP_REPEAT分配失敗時重新分配
__GFP_NOFAILT分配失敗時重新分配,直至成功
__GFP_NORETRY分配失敗時不再重新分配

區(qū)修飾符

區(qū)修飾符說明需要從內(nèi)核空間的哪個區(qū)域中分配內(nèi)存。內(nèi)存分配器默認(rèn)從內(nèi)核空間的ZONE_NORMAL開始逐漸向高端獲取為內(nèi)存請求者分配內(nèi)存區(qū),如果用戶特意需要從ZONE_DMA或ZONE_HOGNMEM獲得內(nèi)存,那么就需要內(nèi)存請求者在內(nèi)存請求函數(shù)中使用以下兩個區(qū)修飾符說明:

Linux的主要內(nèi)核內(nèi)存分配區(qū)修飾符
修飾符說明
__GFP_DMA從ZONE_DMA區(qū)分配內(nèi)存
__GFP_HIGHMEM從ZONE_HIGHMEM區(qū)分配內(nèi)存

類型修飾符

類型修飾符實質(zhì)上是上述所述修飾符的聯(lián)合應(yīng)用。也就是:將上述的某些行為修飾符和區(qū)修飾符,用“|”進(jìn)行連接并另外取名的修飾符。這里就不多介紹了。

內(nèi)核常用內(nèi)存分配及地址映射函數(shù)

函數(shù)vmalloc()

函數(shù)vmalloc()在vmalloc分配區(qū)分配內(nèi)存,可獲得虛擬地址連續(xù),但并不保證其物理頁框連續(xù)的較大內(nèi)存。與物理空間的內(nèi)存分配函數(shù)malloc()有所區(qū)別,vmalloc()分配的物理頁不會被交換出去。函數(shù)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);
}

其中,參數(shù)size為所請求內(nèi)存的大小,返回值為所獲得內(nèi)存虛擬地址指針。

與vmalloc()配套的釋放函數(shù)如下:

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

其中,參數(shù)addr為待釋放內(nèi)存指針。

函數(shù)kmalloc()

kmalloc()是內(nèi)核另一個常用的內(nèi)核分配函數(shù),它可以分配一段未清零的連續(xù)物理內(nèi)存頁,返回值為直接映射地址。由kmalloc()可分配的內(nèi)存最大不能超過32頁。其優(yōu)點是分配速度快,缺點是不能分配大于128KB的內(nèi)存頁(出于跨平臺考慮)。

在linux/slab.h文件中,該函數(shù)的原型聲明如下:

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);
}

其中,參數(shù)size為以字節(jié)為單位表示的所申請空間的大?。粎?shù)flags決定了所分配的內(nèi)存適合什么場合。

與函數(shù)kmalloc()對應(yīng)的釋放函數(shù)如下:

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);
}

小結(jié)一下,kmalloc、vmalloc、malloc的區(qū)別:

  • kmalloc和vmalloc是分配的是內(nèi)核的內(nèi)存,malloc分配的是用戶的內(nèi)存;

  • kmalloc保證分配的內(nèi)存在物理上是連續(xù)的,vmalloc保證的是在虛擬地址空間上的連續(xù),malloc不保證任何東西;

  • kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大;

  • vmalloc比kmalloc要慢。

也就是說:kmalloc、vmalloc這兩個函數(shù)所分配的內(nèi)存都處于內(nèi)核空間,即從3GB~4GB;但位置不同,kmalloc()分配的內(nèi)存處于3GB~high_memory(ZONE_DMA、ZONE_NORMAL)之間,而vmalloc()分配的內(nèi)存在VMALLOC_START~4GB(ZONE_HIGHMEM)之間,也就是非連續(xù)內(nèi)存區(qū)。一般情況下在驅(qū)動程序中都是調(diào)用kmalloc()來給數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,而vmalloc()用在為活動的交換區(qū)分配數(shù)據(jù)結(jié)構(gòu),為某些I/O驅(qū)動程序分配緩沖區(qū),或為模塊分配空間。

linux驅(qū)動程序運行空間是什么

函數(shù)alloc_pages()

與上述在虛擬空間分配內(nèi)存的函數(shù)不同,alloc_pages()是在物理內(nèi)存空間分配物理頁框的函數(shù),其原型如下:

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);
}

其中,參數(shù)order表示所分配頁框的數(shù)目,該數(shù)目為2^order。order的最大值由include/Linux/Mmzone.h文件中的宏MAX_ORDER決定。參數(shù)gfp_mask為說明內(nèi)存頁框分配方式及使用場合。

函數(shù)返回值為頁框塊的第一個頁框page結(jié)構(gòu)的地址。

調(diào)用下列函數(shù)可以獲得頁框的虛擬地址:

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;
}

使用函數(shù)alloc_pages()獲得的內(nèi)存應(yīng)該使用下面的函數(shù)釋放:

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);
	}
}

函數(shù)kmap()

kmap()是一個映射函數(shù),它可以將一個物理頁框映射到內(nèi)核空間的可持久映射區(qū)。這種映射類似于內(nèi)核ZONE_NORMAL的固定映射,但虛擬地址與物理地址的偏移不一定是PAGE_OFFSET。由于內(nèi)核可持久映射區(qū)的容量有限(總共只有4MB),因此當(dāng)內(nèi)存使用完畢后,應(yīng)該立即釋放。

函數(shù)kmap()的函數(shù)原型如下:

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

小結(jié)

由于CPU的地址總線只有32位, 32的地址總線無論是從邏輯上還是從物理上都只能描述4G的地址空間(232=4Gbit),在物理上理論上最多擁有4G內(nèi)存(除了IO地址空間,實際內(nèi)存容量小于4G),邏輯空間也只能描述4G的線性地址空間。

為了合理的利用邏輯4G空間,Linux采用了3:1的策略,即內(nèi)核占用1G的線性地址空間,用戶占用3G的線性地址空間。所以用戶進(jìn)程的地址范圍從0~3G,內(nèi)核地址范圍從3G~4G,也就是說,內(nèi)核空間只有1G的邏輯線性地址空間。

如果Linux物理內(nèi)存小于1G的空間,通常內(nèi)核把物理內(nèi)存與其地址空間做了線性映射,也就是一一映射,這樣可以提高訪問速度。但是,當(dāng)Linux物理內(nèi)存超過1G時,線性訪問機制就不夠用了,因為只能有1G的內(nèi)存可以被映射,剩余的物理內(nèi)存無法被內(nèi)核管理,所以,為了解決這一問題,Linux把內(nèi)核地址分為線性區(qū)和非線性區(qū)兩部分,線性區(qū)規(guī)定最大為896M,剩下的128M為非線性區(qū)。從而,線性區(qū)映射的物理內(nèi)存成為低端內(nèi)存,剩下的物理內(nèi)存被成為高端內(nèi)存。與線性區(qū)不同,非線性區(qū)不會提前進(jìn)行內(nèi)存映射,而是在使用時動態(tài)映射。

低端內(nèi)存又分成兩部分:ZONE_DMA:內(nèi)核空間開始的16MB、ZONE_NORMAL:內(nèi)核空間16MB~896MB(固定映射)。剩下的就是高端內(nèi)存:ZONE_HIGHMEM :內(nèi)核空間896MB ~ 結(jié)束(1G)。

根據(jù)應(yīng)用目標(biāo)不同,高端內(nèi)存區(qū)分vmalloc區(qū)、可持久映射區(qū)和臨時映射區(qū)三部分。vmalloc區(qū)使用vmalloc()函數(shù)進(jìn)行分配;可持久映射區(qū)使用allc_pages()獲得對應(yīng)的 page,在利用kmap()函數(shù)直接映射;臨時映射區(qū)一般用于特殊需求。

用戶空間和內(nèi)核空間
內(nèi)核空間(3G~4G)

高端內(nèi)存(3G+high_memory~4G)ZONE_HIGHMEM

非線性映射區(qū)

臨時映射區(qū)
可持久映射區(qū)
vmalloc區(qū)

低端內(nèi)存(3G~3G+high_memory-1)

線性映射區(qū)(固定映射區(qū))

ZONE_NORMAL
ZONE_DMA
用戶空間(0~3G-1)頁目錄-->中間頁目錄-->頁表

到此,關(guān)于“l(fā)inux驅(qū)動程序運行空間是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI