中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux中內核頁表和進程頁表有什么關系

發布時間:2022-01-05 09:41:49 來源:億速云 閱讀:327 作者:小新 欄目:云計算

這篇文章給大家分享的是有關Linux中內核頁表和進程頁表有什么關系的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

初學內核時,經常被“內核頁表”和“進程頁表”搞暈,不知道這到底是個啥東東,跟我們平時理解的頁表有什么關系。

內核頁表:即書上說的主內核頁表,在內核中其實就是一段內存,存放在主內核頁全局目錄init_mm.pgd(swapper_pg_dir)中,硬件并不直接使用。

進程頁表:每個進程自己的頁表,放在進程自身的頁目錄task_struct.pgd中。

在保護模式下,從硬件角度看,其運行的基本對象為“進程”(或線程),而尋址則依賴于“進程頁表”,在進程調度而進行上下文切換時,會進行頁表的切換:即將新進程的pgd(頁目錄)加載到CR3寄存器中。從這個角度看,其實是完全沒有用到“內核頁表”的,那么“內核頁表”有什么用呢?跟“進程頁表”有什么關系呢?

1、內核頁表中的內容為所有進程共享,每個進程都有自己的“進程頁表”,“進程頁表”中映射的線性地址包括兩部分:

用戶態

內核態

其中,內核態地址對應的相關頁表項,對于所有進程來說都是相同的(因為內核空間對所有進程來說都是共享的),而這部分頁表內容其實就來源于“內核頁表”,即每個進程的“進程頁表”中內核態地址相關的頁表項都是“內核頁表”的一個拷貝。

2、“內核頁表”由內核自己維護并更新,在vmalloc區發生page fault時,將“內核頁表”同步到“進程頁表”中。以32位系統為例,內核頁表主要包含兩部分:

線性映射區

vmalloc區

其中,線性映射區即通過TASK_SIZE偏移進行映射的區域,對32系統來說就是0-896M這部分區域,映射對應的虛擬地址區域為TASK_SIZE-TASK_SIZE+896M。這部分區域在內核初始化時就已經完成映射,并創建好相應的頁表,即這部分虛擬內存區域不會發生page fault。

vmalloc區,為896M-896M+128M,這部分區域用于映射高端內存,有三種映射方式:vmalloc、固定、臨時,這里就不像述了。

以vmalloc為例(最常使用),這部分區域對應的線性地址在內核使用vmalloc分配內存時,其實就已經分配了相應的物理內存,并做了相應的映射,建立了相應的頁表項,但相關頁表項僅寫入了“內核頁表”,并沒有實時更新到“進程頁表中”,內核在這里使用了“延遲更新”的策略,將“進程頁表”真正更新推遲到第一次訪問相關線性地址,發生page fault時,此時在page fault的處理流程中進行“進程頁表”的更新:

/*

     * 缺頁地址位于內核空間。并不代表異常發生于內核空間,有可能是用戶

     * 態訪問了內核空間的地址。

     */

    if (unlikely(fault_in_kernel_space(address))) {

        if (!(error_code & (PF_RSVD | PF_USER | PF_PROT))) {

            //檢查發生缺頁的地址是否在vmalloc區,是則進行相應的處理

            if (vmalloc_fault(address) >= 0)

                return;

/*

  * 對于發生缺頁異常的指針位于vmalloc區情況的處理,主要是將

  * 主內核頁表向當前進程的內核頁表同步。

  */

static noinline __kprobes int vmalloc_fault(unsigned long address)

{

    unsigned long pgd_paddr;

    pmd_t *pmd_k;

    pte_t *pte_k;

 

    /* Make sure we are in vmalloc area: */

    /* 區域檢查 */

    if (!(address >= VMALLOC_START && address < VMALLOC_END))

        return -1;

 

    WARN_ON_ONCE(in_nmi());

 

    /*

     * Synchronize this task's top level page-table

     * with the 'reference' page table.

     *

     * Do _not_ use "current" here. We might be inside

     * an interrupt in the middle of a task switch..

     */

     /*獲取pgd(最頂級頁目錄)地址,直接從CR3寄存器中讀取。

     *不要通過current獲取,因為缺頁異常可能在上下文切換的過程中發生,

     *此時如果通過current獲取,則可能會出問題*/

    pgd_paddr = read_cr3();

    //從主內核頁表中,同步vmalloc區發生缺頁異常地址對應的頁表

    pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);

    if (!pmd_k)

        return -1;

    //如果同步后,相應的PTE還不存在,則說明該地址有問題了

    pte_k = pte_offset_kernel(pmd_k, address);

    if (!pte_present(*pte_k))

        return -1;

 

    return 0;

}

感謝各位的閱讀!關于“Linux中內核頁表和進程頁表有什么關系”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

隆回县| 兴业县| 闽清县| 苏州市| 德格县| 县级市| 泰和县| 伊吾县| 衡南县| 余庆县| 新宾| 鹿泉市| 蓬莱市| 鲁山县| 定安县| 浪卡子县| 康平县| 樟树市| 饶河县| 济阳县| 汪清县| 玉龙| 肇庆市| 怀远县| 商都县| 兴隆县| 绵阳市| 遂昌县| 阿勒泰市| 四会市| 大石桥市| 龙胜| 西乌珠穆沁旗| 河北省| 黄大仙区| 临朐县| 尼勒克县| 镇赉县| 清新县| 瑞丽市| 沁源县|