Linux(0.11版本)記憶體管理-函數詳解__安卓

來源:互聯網
上載者:User

0.11核提供的記憶體管理函數大部分在memery.c中,我將其中的函數從功能上分為三類:記憶體的分配與釋放、頁異常處理和記憶體初始化。第一類主 要包括單個物理頁的操作和頁表的操作,單個物理頁的操作就是一個物理頁的申請、映射和釋放;頁表操作主要是多個頁表的釋放、複製。第二類主要是處理缺頁異 常和防寫保護異常的中斷處理函數。第三類就是一個函數負責記憶體的初始化工作。

一、記憶體的分配與釋放

1、get_free_page():在主記憶體區中申請一空閑物理頁。

   首先掃描mem_map[],從末端向前尋找值為0的元素,找到後將它的值置成1,並根據這個元素的在mem_map[]中的索引值得到物理頁的地址,再將物理頁中的4K位元組清零,最後返回物理地址。

2、free_page():釋放指定物理地址處的物理頁。

   在驗證了這個地址的有效性之後,根據它換算出對應的頁地址:(addr-1M)/4K,再利用此地址值作為索引在mem_map[]中找到對應項,將其清零。

3、free_page_tables():釋放從指定線性地址開始的若干個頁表以及它對應的物理頁。

   先判斷傳入的線性地址是否有效,即是否在4MB邊界上,然後就算出它所佔的頁目錄項的個數和第一個目錄項的地址,接著從第一個目錄項開始,對於可用的目錄 項(也就是p=1:存在對應的頁表)就根據目錄項得到頁表的地址,從而釋放頁表中的所有記錄著的物理頁(free_page)並將此頁表項清零,之後釋放 掉這個頁表本身所佔的物理頁並將它對應的頁目錄項清零。直到處理完最後一個頁目錄項。最後重新整理TLB。

4、copy_page_tables():複製指定線性地址開始的若干個頁表到指定的目標線性地址處。

   這個函數是fork一個進程時候用到的,它讓子進程共用父進程的實體記憶體。在驗證了地址的邊界性之後,換算出頁目錄項表中的來源目錄項起始地址和目標目錄項 的起始地址以及要複製的頁目錄項的個數。然後開始複製工作:首先申請一頁記憶體存放新頁表,然後設定對應的頁目錄項,再迴圈複製源頁表中各頁表項到新頁表中 (對於核心進程只複製前160項就行,因為核心模組不超過640K),並將各個頁表項設為唯讀,最後根據各個頁的物理地址在mem_map[]中將此頁對 應的元素的值加1(表示引用次數加1)。然後迴圈這樣的複製工作直到複製完所有的頁表。

5、put_page():將一物理頁映射到指定的線性地址空間處。

   也就是根據線性地址找到對應的頁表項,將這個頁表項中的值設為這個物理頁的物理地址。這個函數一般在get_free_page()後使用。在驗證了地址 有效性之後,先根據線性地址的高10位換算出頁目錄項的地址,在從頁目錄項中得到頁表地址,再根據線性地址的中間10位得到頁表項地址。最後將在這個頁表 項中設定它所映射的物理頁地址和一些頁資訊。

6、get_empty_page():get_free_page()和put_page()的結合。

二、頁異常處理相關函數

1、up_wp_page():取消指定頁表項對應的物理頁的防寫保護。

   這個函數是處理頁防寫保護的情況。它首先檢查這個頁是否只被一個進程使用(mem_map[]中對應的元素是1),如果是直接將它改為可寫,如果它被多個進 程使用,則申請一個頁面,然後改寫頁表項:更新新物理頁的地址、設為可讀寫,接著將原物理頁的引用次數減1,最後複製原物理頁的內容到新物理頁中後重新整理 TLB。

2、do_wp_page():中斷處理函數:處理防寫保護異常

   根據線性地址得到頁表項地址,並把它作為參數調用up_wp_page()。

3、write_verify():檢查頁面是否可寫,如果不可寫複製頁面。

   根據給定的線性地址得到頁表項,根據頁表項判斷對應的物理頁是否可寫,如果不可寫,則調用un_wp_page(),完成新頁面的複製。

4、try_to_share():讓當前進程的指定邏輯地址共用另一個進程這個邏輯地址對應的物理頁。

   當一個進程與另一個進程對應同一個可執行程式的時候,可以讓一個進程共用另一個進程的實體記憶體。首先根據邏輯地址分別得到當前進程和目標進程的頁目錄項, 然後根據目標進程的頁目錄項中得到頁表從而得到頁表項,然後判斷這個頁表項對應的物理頁是否被修改過,如果沒被修改過,則表示可以被共用。接著得到當前進 程的要操作的頁表項,並將此頁表的內容設為剛才得到的目的進程頁表項的內容,最後將這兩個頁表項都設為唯讀。

5、share_page():共用頁面

   找到與當前進程對應同一個可執行程式的進程,然後調用try_to_share()進行頁面的共用。尋找這個進程的方法是先得到當前進程的對應的可執行程式的i節點,然後掃描整個task數組,找到與當前進程i節點相同的進程。

6、do_no_page():中斷處理函數:缺頁處理

   缺頁有兩種情況,一種是動態申請記憶體導致的缺頁,一種訪問進程代碼或者資料時候缺頁。先根據線性地址和當前進程的起始地址得到邏輯地址,判斷這個邏輯地址 是否在程式碼片段和資料區段範圍之外,如果在這個範圍之外說明是在堆段中,則表示這是動態申請記憶體引起的缺頁,這個時候,用get_empty_page()就 可以解決問題了。如果在這個範圍之內,說明是反問程式的代碼或者資料引起的缺頁,整個時候,需要從磁碟的可執行程式中複製相應頁面到記憶體中:先申請一塊物 理記憶體頁,接著根據邏輯地址得到可執行檔中對應的邏輯塊(每塊大小1KB)號,然後將連續的四個邏輯塊複製到新申請的物理頁中,在處理完一些無用資訊 (有可能讀入的4個邏輯塊中實際的有用資訊不足4KB)之後,完成物理頁到線性地址的映射。

三、記憶體的初始化:mem_init()

    這個函數在main初始化的時候被調用的,前面已經說過Linux對記憶體的管理主要是通過mem_map[]完成的,記憶體的初時話,主要就是對 mem_map[]進行初始化:就是將1M以上的記憶體空間中的主記憶體部分在mem_map[]對應的元素置為0,其它部分置位佔用狀態。

    附:0.11核記憶體管理中還有一個檔案,page.s,這個檔案主要是頁異常引起中斷的中斷處理函數,具體的就是根據異常類型調用不同的處理函數:do_no_page()、do_wp_page()。

    至此,Linux0.11核的記憶體管理的學習,我打算告一段落,下面我計劃學習Linxu的設配管理,主要是設配驅動。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.