產生頁面異常的原因:
(1).目標頁面不存在(頁表項全0,即該線性位址與實體地址尚未建立對映或者已經撤銷);
(2).相應的物理頁面不在記憶體中(頁表項非空,但p標誌=0,比如在swap分割槽或磁碟檔案上);
(3).訪問許可權不符合(此時頁表項p標誌=1,比如企圖寫唯讀頁面).
當出現上面情況之一,那麼就會產生頁面page fault異常。產生異常的線性位址儲存在cr2中,所以在do_page_fault()中首先將這個位址讀進來,接著:
一. 看該線性頁表項是否為全0.不是全0說明對映已經建立,只是物理頁面在交換裝置中,那麼就從交換裝置上把頁面換進來. 如果頁表項全0說明對映還沒建立,那麼進入第二步.
二. 最一般的情況,檢查目標線性位址是否是無效的.
如果目標位址(>3gb),那麼就要看是否本次page fault異常是核心態引起的,是則跳轉執行特定**,不是就說明線性位址無效.
如果目標位址在程序位址空間(<3gb)並且不是在中斷中,那麼用find_vma()從所屬程序所用的線性區煉表裡找到"結束位址大於該位址的第乙個線性區vma",結果:
(1)如果找不到上述線性區vma,則線性位址越界了,跳到bad_area, 最終segment fault.
(2) 如果找到了上述線性區vma,但目標位址不在找到的vma區間內(即 addrstart),那麼說明本次異常要麼是為了擴充套件堆疊expand_stack(滿足:找到的vma設定 vm_growsdown標誌,且addr+32>regs->esp),要麼也是無效位址跳到bad_area,最終segment fault.
(3)如果找到了上述線性區vma,並且目標位址在vma區間內,那麼跳轉到good_area. 在good_area檢查滿足訪問許可權(讀/寫/執行)後,就handle_mm_fault()最終handle_pte_fault()決定來請求調 頁(demand paging)或寫時複製(cow).這才是處理缺頁異常的核心,下面集中講這一點。
三. 上面handle_pte_fault()做得事情分成2種情況:
(1) 目標位址對應的頁表項present標誌=0,也就是由最開頭產生頁面異常的原因(1)和(2)。處理辦法:對於(1)目標頁面根本就不存在,那麼 do_no_page()分配乙個物理頁面並建立對映; 對於(2)目標頁面不在記憶體中,那麼就從磁碟檔案或交換分割槽中換入記憶體,分別對應do_file_page()和do_swap_page().
(2)目標位址對應的頁表項present標誌=1,也就是由最開頭產生頁面異常的原因(3),處理辦法: 分配乙個新頁框,實現寫時複製(cow).
缺頁異常處理 do page fault
regs 發生異常時暫存器的值 error code 5位的值,第3位標誌異常發生在核心態還是使用者態 do page fault函式 獲得產生缺頁異常的位址,該位址儲存在cr2暫存器 address read cr2 檢查線性位址是否屬於第4個g 如果核心訪問不存在的記憶體頁框,則執行vmallo...
linux缺頁異常處理 核心空間
缺頁異常被觸發通常有兩種情況 程式設計的不當導致訪問了非法的位址 訪問的位址是合法的,但是該位址還未分配物理頁框.下面解釋一下第二種情況,這是虛擬記憶體管理的乙個特性。儘管每個程序獨立擁有3gb的可訪問位址空間,但是這些資源都是核心開出的空頭支票,也就是說程序手握著和自己相關的乙個個虛擬記憶體區域 ...
Linux 記憶體管理 缺頁異常的幾種原因
給定乙個線性位址,mmu 通過頁目錄表 頁表的轉換,找到對應的實體地址。在這個過程中,如果因某種原因導致無法訪問到最終的物理記憶體單元,cpu 會產生一次缺頁異常,從而進入缺頁異常處理程式 總結一下,缺頁異常的原因有以下幾種 1 導致缺頁異常的線性位址根本不在程序的 虛存區間 中,段錯誤。棧擴充套件...