天天看點

linux管理核心,linux 核心管理子系統

原創:http://blog.chinaunix.net/uid/23795897.html,參考國嵌教育,在此感謝國嵌的所有老師。

一、

linux管理核心,linux 核心管理子系統

linux管理核心,linux 核心管理子系統

二、位址是32位,就有4G的空間,0-3G為使用者空間,3-4G為核心空間。

核心空間又分為4個部分,黑色1、表示直接映射區,3G~3G+896M位址,這個隻能通路低端位址,在3G+896M下3G以上的稱低端記憶體,以上的稱高端記憶體。這個是直接的3G+實體位址。

黑色2、vmalloc區域,可以通路低端和高端位址。

黑色3、永久核心映射區,隻能通路高端位址。

黑色4、表示固定的,通路一些特殊的寄存器

注:紅色1是實體記憶體配置設定。

紅色2是實體位址與虛拟位址的映射

三、虛拟位址如何轉換成實體位址:

linux管理核心,linux 核心管理子系統

首先先取出高10位可以找到頁目錄,在中間的10位找到頁表,在11位找到實體頁。

四、實體記憶體配置設定:

linux管理核心,linux 核心管理子系統

實體記憶體:detasheet裡面的寄存器位址等。

虛拟記憶體:程式用到的位址。

但malloc時隻有配置設定到虛拟的記憶體。當要用到的時候才有用到實體記憶體。kmalloc是真正的實體記憶體。slab會配置設定一個記憶體池。

linux管理核心,linux 核心管理子系統
linux管理核心,linux 核心管理子系統
linux管理核心,linux 核心管理子系統
linux管理核心,linux 核心管理子系統

以下轉載:http://www.eefocus.com/spencer/blog/13-04/293210_d92e2.html

一般情況下,Linux系統中,程序的4GB記憶體空間被劃分成為兩個部分------使用者空間和核心空間,大小分别為0~3G,3~4G。

使用者程序通常情況下,隻能通路使用者空間的虛拟位址,不能通路到核心空間。

每個程序的使用者空間都是完全獨立、互不相幹的,使用者程序各自有不同的頁表。而核心空間是由核心負責映射,它并不會跟着程序改變,是固定的。核心空間位址有自己對應的頁表,核心的虛拟空間獨立于其他程式。

3~4G之間的核心空間中,從低位址到高位址依次為:實體記憶體映射區—隔離帶—vmalloc虛拟記憶體配置設定區—隔離帶—高端記憶體映射區—專用頁面映射區—保留區。

linux管理核心,linux 核心管理子系統

【核心空間記憶體動态申請】

主要包括三個函數:kmalloc(), __get_free_pages, vmalloc。

kmalloc(),

__get_free_pages申請的記憶體位于實體位址映射區,而且在實體上也是連續的,它們與真實的實體位址隻有一個固定的偏移,是以存在較簡單的轉換關系。而vmalloc申請的記憶體位于vmalloc虛拟記憶體配置設定區(這些區都是以線性位址為度量),它在虛拟記憶體空間給出一塊連續的記憶體區,實質上,這片連續的虛拟記憶體在實體記憶體中并不一定連續,而vmalloc申請的虛拟記憶體和實體記憶體之間也沒有簡單的換算關系。

因為vmalloc申請的在虛拟記憶體空間連續的記憶體區在實體記憶體中并不一定連續,可以想象為了完成vmalloc,新的頁表需要被建立,是以,知識調用vmalloc來配置設定少量記憶體是不妥的。

一般來講,kmalloc用來配置設定小于128K的記憶體,而更大的記憶體塊需要用vmalloc來實作。

【虛拟位址與實體位址關系】

對于核心實體記憶體映射區的虛拟記憶體(用kmalloc(), __get_free_pages申請的),使用virt_to_phys()和phys_to_virt()來實作實體位址和核心虛拟位址之間的互相轉換。它實際上,僅僅做了3G的位址移位。

上述方法适用于正常記憶體(核心實體記憶體映射區),高端記憶體的虛拟位址與實體位址之間不存在如此簡單的換算關系。因為它涉及到了分離實體頁的頁表控制機制。

【ioremap】

在ARM中,裝置的寄存器或者存儲塊的這部分空間屬于記憶體空間的一部分,我們稱之為IO記憶體。

在核心中通路IO記憶體之前,我們隻有IO記憶體的實體位址,這樣是無法通過軟體直接通路的,需要首先用ioremap()函數将裝置所處的實體位址映射到核心虛拟位址空間(3GB~4GB)。然後,才能根據映射所得到的核心虛拟位址範圍,通過通路指令通路這些IO記憶體資源。

在将I/O記憶體資源的實體位址映射成核心虛位址後,理論上講我們就可以象讀寫RAM那樣直接讀寫I/O記憶體資源了。為了保證驅動程式的跨平台的可移植性,我們應該使用Linux中特定的函數來通路I/O記憶體資源,而不應該通過指向核心虛位址的指針來通路。

【mmap】

用mmap映射一個裝置,意味着使使用者空間的一段位址關聯到裝置記憶體上,這使得隻要程式在配置設定的位址範圍内進行讀取或者寫入,實際上就是對裝置的通路。這種資料傳輸是直接的,不需要用到核心空間作為資料轉移的中間站。

remap_page_range函數的功能是構造用于映射一段實體位址的新頁表,實作了核心空間與使用者空間的映射。

在核心驅動程式的初始化階段,通過ioremap()将實體位址映射到核心虛拟空間;在驅動程式的mmap系統調用中,使用remap_page_range()将該塊ROM映射到使用者虛拟空間。這樣核心空間和使用者空間都能通路這段被映射後的虛拟位址。

Ioremap:

程序空間?核心空間?IO記憶體

其中,後面兩個指的是同一段實體記憶體區域,隻是一個為虛拟位址,一個為實體位址。程序空間和核心空間對應着不同的實體位址,它們之間的資料傳遞,是實際的資料的拷貝。

Mmap:

程序空間?IO記憶體

其中,程序空間mmap得到的那段虛拟位址跟IO記憶體對應着同一段實體位址。這個過程沒有額外的資料中轉,讀寫都直接針對硬體的實體位址進行。

一般來講,小資料量的傳輸用ioremap()就足夠了,

【IO記憶體的一般通路方法】

1.首先是調用request_mem_region()申請資源,即告訴核心,本驅動正在使用這段實體記憶體,其他驅動不得通路它們。在裝置驅動子產品加載或open()函數中進行。

2.接着講寄存器位址通過ioremap()映射到核心空間虛拟位址,之後就可以通過Linux裝置通路程式設計接口通路這些裝置的寄存器了。在裝置驅動初始化、write(),read(),ioctl()函數中進行。

3.通路完成之後,應對ioremap()申請的虛拟位址進行釋放,并釋放release_mem_region()申請的IO記憶體資源。在裝置驅動子產品解除安裝或release()函數中進行

繼續閱讀