1. 程式人生 > >【迅為iTop4412學習筆記】10.瞭解實體地址和虛擬地址

【迅為iTop4412學習筆記】10.瞭解實體地址和虛擬地址

宣告

以下都是我剛開始看驅動視訊的個人強行解讀,如果有誤請指出,共同進步。

本節目標

瞭解實體地址和虛擬地址,MMU是關鍵

在之前我們對linux驅動已經有了一個大概印象,而編寫的程式碼也都是學習性質的編寫,在本節之後就開始逐漸深入。

首先我們要用到的就是迅為提供的開發板的原理圖,他的位置是
iTOP-4412精英版光碟資料\01_PCB_SCH_DATASHEET下的iTOP4412_MAIN_CLASICS_V3_2_20180205資料夾下,而怎麼去看這些就好好看迅為的視訊即可。

對於用過微控制器的人來說,這一節應該是比較好理解的。

我們以LED為例,一步步的查詢如何連線,最終找到GPL2_0就是迅為開發板4412晶片接LED的管腳

所以我們要編寫驅動,最終還是要操控GPL2_0的暫存器,開啟4412晶片的datasheet搜GPL2CON就能找到他的硬體地址。

那是不是我們直接操控他的硬體地址就行了呢?不是。

我們要謹記,微控制器和linux是不一樣的。如果把linux當微控制器去使,他就只是一個微控制器,沒有系統層面的思想,這樣是沒有靈魂的!

微控制器我們是怎麼玩的?
我們知道程式其實都是操作CPU的暫存器。程式就是告訴CPU,你的哪個暫存器要怎麼做。程式在哪?舉個例子,我們電腦上寫程式,寫好了可不放在硬碟麼…

對於linux來說
linux是個系統,也是一個平臺,做事要講究,我們不能什麼直接操作暫存器。對於實體地址,linux都把他包裝起來了,不直接開放給我們操作。我們程式想操作,要經過linux的允許。

首先講一下,我們要知道微控制器和ARM Linux的區別是什麼。百度一搜就知道多了一個cache和mmu記憶體管理單元。

引入記憶體概念

CPU應該都知道,他的速度是非常快的,硬碟則是非常慢的。所以CPU直接讀硬碟的程式,那著急死了。
因此我們引入了記憶體,他的速度介於CPU和硬碟之間作為一箇中轉站,這樣大家就都好受一點了。

對於微控制器,實時效能要求較高,操作GPIO是第一位的,所以CPU要等待引腳的操作完成,再去做別的事情。因此微控制器只需要這麼多就可以了。

引入cache快取概念

但是對於linux來說,他是一個平臺,他的夢想遠大,怎麼能滿足這麼一點功能呢?

雖然引入了記憶體,但這個速度還是不夠快,所以在CPU和記憶體直接又引入了一個cache,他的速度介於CPU和記憶體之間。

這下速度差不多了,CPU -> cache -> 記憶體 -> 硬碟,有這麼多的快取硬體,這下大家的速度都匹配了。(不要問為什麼不全部用cache,貴啊…)

這下速度夠快了,linux還是覺得差了點。

引入MMU記憶體管理單元的概念

我們隨便說一臺電腦的配置,什麼i7的CPU(隨便舉個例子,快取是幾M),8G的記憶體,1T的硬碟。

速度夠了,但是好像大家大小不一樣啊,我要是有個10G的程式,8G記憶體那不是裝不下?難道就執行不了了?

linux決定搞一些騷操作,我要用8G的記憶體也能載入10G的程式。

他引入了一個虛擬記憶體

10G的程式,難不成10G都會用到?所以程式常用的部分就載入進記憶體,不常用的還放在硬盤裡,當程式需要呼叫不在記憶體的部分程式的時候,再從硬盤裡讀。雖然慢了點,但好在能用8G的記憶體載入10G的程式了。

但是問題來了,我怎麼知道你程式在哪?

此時MMU出現了,他不存這些資料,而是建立一個“表格”,他儲存了虛擬地址和實體地址的對映關係。當你操作這些虛擬地址的時候,MMU就會找到他的實體地址去呼叫它。

我們假設我們的電腦的配置很低(1G記憶體,10G硬碟)
現在我們運行了一個4G的程式。我們CPU開始執行程式,程式要操作,但是操作就要有地址,那麼則去操作那些虛擬地址,而MMU再找到虛擬地址對應的真正的實體地址,最後從實體地址裡真正的讀程式去控制CPU裡的暫存器。

為什麼ARM的linux要做比微控制器這麼多複雜的事情呢?

  1. 即使你的記憶體不夠大,也能跑比記憶體還要大的程式(慢了點,也比跑不了好吧!)
  2. 直接操作CPU的暫存器雖然快,但其實是一個很危險的事情,linux要統一管理

虛擬記憶體是不是無限大呢?

不是,就像牛皮一樣,你可以吹牛皮,但是你不能吹破了。

對於32位的CPU,他最多尋找2^32=4G個地址,那麼能操控的地址最大也就是4G。

  1. 假如你不富有,只有1G的記憶體條,那麼系統可以最大幫你虛擬4G的記憶體出來(4G的程式不是同時在跑,所以用哪一部分,那裡載入硬盤裡的程式到1G記憶體裡去跑),你就能跑4G的程式了。
  2. 假如你很有錢,有4G的記憶體條,4G的虛擬地址和4G的實體地址一一對應,你的程式全部載入在記憶體條裡,程式跑的自然快很多(因為記憶體比硬碟快)
  3. 假如你特別有錢,用的8G的記憶體條,那麼恭喜你,你浪費了4G的記憶體,因為32位的CPU最多隻能尋找4G個地址。(所以有傻X用32位的系統但是用8G的記憶體條,盡情的嘲笑他…)

對於64位的CPU,最多能模擬2^64=17179869184G的大小。多麼嚇人的數字。

  1. 假如你不富有,還是用的1G的記憶體條,系統照樣可以用硬碟來當記憶體使,只是硬碟速度慢,跑起程式來也慢。
  2. 假如你有錢,記憶體條你可以使勁加大,因為64位的CPU可以操作的地址太大了,你記憶體夠大,能跑的程式就越多越快(因為都在記憶體)。

所以有錢,就加記憶體,你就可以載入很多程式到記憶體條,因為都在記憶體,所以速度也很快。
但是記憶體大還不夠,你硬碟如果太慢了,記憶體讀的著急死了也讀不進去。所以硬碟雖然大,但硬碟速度也要快,機械硬碟的速度太著急了,用SSD吧,讀寫速度很快。
(emmm…三千預算進卡吧,加錢加到十萬八…)

收尾

對於上系統來說,東西雖然看起來好像變複雜了,但是複雜的同時,也能讓他能做的事變多變強了。
而且這些複雜的東西不需要你全部完成,很多東西都是自動的(不然要系統幹啥)
對於我們編寫驅動來說,只需要操作虛擬地址即可。只要想操作的虛擬地址能對應上我們遙操作的那個實體地址,中間是怎麼實現的自然有晶片廠家來做,他們會提供這個地址是如何對映的,我們只管看晶片手冊,使用對映好的虛擬地址即可。