linux0.11記憶體管理

來源:互聯網
上載者:User

linux0.11記憶體管理 描述linux 0.11的記憶體管理主要內容。 1:記憶體初始化linux 0.11最大支援16MB的實體記憶體。main函數和mem_init函數對記憶體進行了初始化。主要使用數組mem_map[]來標記相應的記憶體頁是否被佔用。 memory_end是用BIOS中斷調用得到的實際記憶體大小。if (memory_end > 16 * 1024 * 1024)    memory_end = 16 * 1024 * 1024;           # 因此最大隻支援16MB記憶體if (memory_end > 12*1024*1024)                buffer_memory_end = 4 * 1024 * 1024;   # buffer_memory_end為快取末端地址,其大小於機器總記憶體大小相關else if (memory_end > 6 * 1024 * 1024)    buffer_memory_end = 2 * 1024 * 1024else    buffer_memory_end = 1*1024*1024 main_memory_start = buffer_memory_end;mem_init(main_memory_start, memory_end);  在mem_init中會對mem_map[]數組進行初始化。在1MB~16MB之間,共有(15 * 1024 * 1024) >> 12 = 3840頁。定義數組mem_map[3840]對應於這段記憶體的每一頁,在main_memory_start和memory_end之間的頁,相應的mem_map[i]的值初始化為0,表示未使用,其餘的項初始化為100,表示被佔用。  2:基本頁面分配函數有幾個基本的頁面分配和釋放的函數。get_free_page():返回一個空閑頁面的物理地址, 該函數就是在mem_map數組中尋找值為0的項,然後轉換成頁面物理地址返回。free_page(phy_addr):釋放phy_addr指向的頁面, 釋放操作就是將phy_addr在mem_map中對應項的值進行減1。get_empty_page(line_addr):該函數的參數指定的是線性地址,要求獲得一頁實體記憶體,並用line_addr指向這頁記憶體。 void get_empty_page(unsigned long address){    unsigned long tmp;        if (!(tmp=get_free_page()) || !put_page(tmp, address)) {        free_page(tmp);        oom();        # 記憶體不夠    }}明顯該函數先調用get_free_page獲得一頁實體記憶體, 然後用put_page對這頁實體記憶體的物理地址和線性地址之間建立映射。 建立映射的過程: 對於32位的線性地址, 高10位表示頁目錄索引, 中間10位為頁表索引, 低12位為頁內位移。因此給定一個線性地址,我們就能通過頁目錄基地址和線性地址高10位來確定它的頁目錄項。在Linux 0.11中,頁目錄基地址就是0。 put_page:    page_table = (unsigned long *) ((line_addr >> 20) & 0xffc)      #  獲得頁目錄項的指標    如果該頁目錄項所指向的頁表是存在的, 則利用線性地址的中間10位,定位到頁表中的相應頁表項,並將物理地址儲存進去即可建立映射。  若頁表不存在,則用get_free_page首先分配一頁作為頁表,再去建立映射。 不管是建立映射還是進行頁表拷貝,都是先考慮頁目錄,再考慮頁表。 3:sys_fork與copy_page_tables函數在sys_fork時會調用copy_process,copy_process中會調用copy_mem函數, 該函數會將父進程的頁表拷貝給子進程,這是父進程和子進程會共用相應的代碼和資料區段,只有當父進程或子進程對共用的記憶體進行寫操作時,才會為子進程分配記憶體,即為寫時複製。 copy_mem是調用copy_page_table進行頁表拷貝的。 copy_page_table(old_data_base, new_data_base, data_limit)將父進程的線性地址old_data_base ~ old_data_base+data_limit對應的頁表,拷貝給子進程。在拷貝過程中,將每個頁表項設定為唯讀, 並且執行相應的mem_map[i]++(相當於添加引用計數) 4:頁出錯異常處理有兩種不同的頁出錯:i)頁表項指向的頁不存在,即頁表項的存在位的值為0.ii)頁保護機制。 寫唯讀頁面時出錯。 但出現頁錯誤時,會發生int 14中斷。系統會執行_page_fault:異常處理代碼。該代碼會根據兩種不同的頁錯誤,分別執行do_no_page和do_wp_page do_wp_page(error_code, address)該函數主要是實現了寫時複製功能, 在copy_page_table時,將父進程和子進程的頁表都設定成了唯讀,當訪問了其中一個頁面後,會觸發中斷並執行do_wp_page函數。此函數會分配一頁新的實體記憶體, 並將相應的頁表項設成可讀寫。 do_no_page(error_code, address)該函數可處理兩種情況:i)在應用程式指派記憶體時,核心並不會實際分配實體記憶體, 只有在訪問相應記憶體時,才會分配。ii)在執行exec系列函數時,同樣只有在訪問相應記憶體時,才會去讀檔案,對於第一種情況, do_no_page直接調用get_empty_page函數,擷取一頁記憶體。對於第二種情況,有兩步過程。i)調用share_page函數。 該函數的主要目的是共用代碼和資料區段。 如果一個可執行檔,已經有一個進程執行個體在執行,那麼新進程可以和其他進程共用該可執行檔的代碼和資料區段。ii)如果只執行過一次該檔案, 那就先調用get_free_page函數,將檔案內容讀入記憶體,然後用put_page函數建立映射。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.