Linux虛存分析報告.doc_第1頁
Linux虛存分析報告.doc_第2頁
Linux虛存分析報告.doc_第3頁
Linux虛存分析報告.doc_第4頁
Linux虛存分析報告.doc_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

LinuxLinux 虛虛 存存 分分 析析 報報 告告 方方 存存 好好 第一章第一章 前前 言言2 第二章第二章 LINUX 虛存管理概述虛存管理概述3 1 LINUX虛存管理的基本特點3 2 LINUX虛存管理的主要實現(xiàn)技術3 第三章第三章 LINUX 虛存管理數(shù)據(jù)結構虛存管理數(shù)據(jù)結構5 1 32 BIT虛擬地址5 2 LINUX的多級頁表結構5 3 頁表項的格式6 4 動態(tài)地址映射7 5 用戶進程的虛擬內存結構8 6 我們的工作10 第四章第四章 PROCESS 的虛存管理數(shù)據(jù)結構的建立 維護 拆除及相關系統(tǒng)調用流程的虛存管理數(shù)據(jù)結構的建立 維護 拆除及相關系統(tǒng)調用流程11 1 進程的載入 創(chuàng)建及內存管理數(shù)據(jù)結構和鏈結關系的建立11 2 數(shù)據(jù)結構及鏈結關系的拆除 SYS EXIT 13 3 缺頁中斷服務14 第五章第五章 主要函數(shù)分析主要函數(shù)分析16 MEMORY C16 MMAP C22 第六章第六章 后記后記29 第一章第一章 前前 言言 Linux 是一個功能強大的操作系統(tǒng) 而內存管理則是操作系統(tǒng)的核心 它負責管理計 算機系統(tǒng)的存儲器 作為操作系統(tǒng)的核心 必須能夠克服物理內存的局限 使用戶進程在 透明方式下 擁有比實際物理內存大得多的內存 其策略之一就是使用虛擬內存 Linux 成功地實現(xiàn)了以虛擬內存為核心的內存管理策略 強大得分頁機制 公平得交換方式 各 類有效得高速緩存 以及以頁保護為主得保護措施等 內存管理的目的是要盡可能地方便 用戶 同時 Linux 系統(tǒng)通過對用戶進程虛存的有效管理 作到了虛存對一般用戶和 Linux 程序員的透明 本文首先闡述了 Linux 虛存管理以基本特點和主要實現(xiàn)技術 并分析了 Linux 虛存管 理的主要數(shù)據(jù)結構及其相關關系 圍繞它的建立 維護 使用和拆除 作了一個粗淺的剖 析 因本人水平有限 有不當之處 請老師指正 同時應該指出的是本文所做的工作離不 開同組的林濤 徐玫峰和范昭偉同學的幫助 謝謝他們 第二章第二章 Linux 虛存管理概述虛存管理概述 Linux 的內存管理采用頁式管理 使用多級頁表 動態(tài)地址轉換機構與主存 輔存共 同實現(xiàn)虛擬內存 每個用戶 Process 擁有 4GB 的虛擬地址空間 Process 在運行過程中可以 動態(tài)浮動和擴展 為用戶提供了透明的 靈活有效的內存使用方式 下面簡述 Linux 虛存 管理以基本特點和主要實現(xiàn)技術 1 Linux 虛存管理的基本特點虛存管理的基本特點 1 更大的地址空間 虛擬內存可以是系統(tǒng)實際擁有的物理內存的若干倍 因而它使得操作系統(tǒng)看 起來擁有比實際大得多的內存 2 合理的物理內存分配 Linux 通過共享和交換策略 使各個運行的進程能公平地共享內存 3 保護 Linux 存儲管理子系統(tǒng)為每一內存頁設置了 上鎖位 在線性地址及每級頁 表頁項上設置了 讀 寫 位 這樣來確保某一個進程不受其他進程的干擾 即使 某一個進程失敗了 也不會影響到其他進程和操作系統(tǒng)本身 4 共享虛擬內存 Linux 實現(xiàn)的虛擬內存允許兩個進程之間互相共享內存 例如 共享的庫 在 這種情形之下 庫代碼僅存在于一個進程 而不需要為每一個應用都復制一份 2 Linux 虛存管理的主要實現(xiàn)技術虛存管理的主要實現(xiàn)技術 1 請求調頁 demanding paging 與內存擴展 用戶 Process 創(chuàng)建時 并不是將它所需所有頁都分配給相應物理頁 開始時只裝入頁 面中 Process 的第一個頁面 其他頁根據(jù) Process 運行過程的請求從外存調入所需頁面 當 Process 訪問一個頁表項 P 位為 0 的頁中地址時 表示此頁不在主存中 將產(chǎn)生缺頁中斷 系統(tǒng)調用 handle mm fault 處理訪問異常 為之分配相應物理頁后 它再調用 swap in 函數(shù) 從外存中讀入該頁面 Linux 是一種請求式分頁存貯管理 這才使之可以運行大于主存空間的 Process 2 頁換出策略 內存中頁面不足時 Linux 使用頁面 AGE 技術實現(xiàn)了頁淘汰策略的最近最少使用 LRU 算法 即每次換出時 總是選擇最老的頁換出 對易于從其他設備上獲取的非臟 not dirty 頁面 Linux 采用丟棄 discarding 技術 如果發(fā)生過寫操作 則將該頁寫 入系統(tǒng)的 Swapfile 中 這樣就可以加快換入的速度 3 內存共享 Linux 將內存劃分為 4K 大小的頁面 為內存共享提供了基礎 1 不同進程間頁面共享時 可令共享該頁的 Process 的頁表項 pte 均指向該頁 2 對 kernel 代碼和數(shù)據(jù)段的共享 通過 Process 創(chuàng)建時 fork 函數(shù)將 kernel 代碼和數(shù) 據(jù)段映射到用戶虛存的 3GB 4GB 的空間中去 所以每個 Process 都可以通過一定方式共享 kernel 的代碼和數(shù)據(jù)段 4 內存保護 采用了 Hole 技術 虛存段的保護 地址轉換機構 頁表存取控制位 R W 位 等 技術實現(xiàn)了內存保護 Hole 技術 物理內存前 4K 是一空頁 empty zero page 用來捕獲 NULL 指 針的異常訪問 在 Process 每個虛存段后 都有一個 4K 的 Hole 用來捕獲虛存段的 越界訪問 虛存段保護方式 主存中虛存段的全部或部分可以設為保護方式 防止非法訪問 頁表項存取控制位 R W 位 頁表項以 R W 位表示此頁的存取權限 1 為 可讀寫 0 為不可讀寫 可用來防止越權訪問 地址轉換機構 分頁存貯管理方法中 地址轉換機構進行的頁面映象實際上防止 了各 Process 的主存塊間互不干擾 起到 Process 隔離的作用 5 動態(tài)地址變換 利用 i386 的地址變換機構 Linux 實現(xiàn)了動態(tài)地址變換 Process 執(zhí)行時訪問到某一虛擬 地址時才確定其對應的物理地址 這種方式為 Process 存貯塊的動態(tài)和動態(tài)擴展提供了基 礎 第三章第三章 Linux 虛存管理數(shù)據(jù)結構虛存管理數(shù)據(jù)結構 1 32 bit 虛擬地址虛擬地址 在 Linux 中 4GB 的虛存需通過 32 bit 地址進行尋址 Linux 中虛擬地址與線形地址 為同一概念 虛擬地址被分割成 3 個子位段 其中 2 個子位段包含 10 位 1 個子位段包 含 12 位 如圖 2 1 所示 123 圖 1 32 位虛擬地址 3 個子位段分別表示不同含義 子位段 1 指向被稱作頁目錄 PGD 的一張表 子位段 2 指向被稱作頁表 PTE 的一張表 子位段 3 指向頁內地址 2 Linux 的多級頁表結構的多級頁表結構 標準的 Linux 的虛存頁表為三級頁表 依次為頁目錄 Page Directory PGD 中間頁目 錄 Page Middle Directory PMD 頁表 Page Table PTE 如圖 2 2 所示 PGD PMD PTE PAGE FRAME 圖 2 Linux 的多級頁表結構 在 i386 機器上 Linux 的頁表結構實際為兩級 PGD 和 PMD 頁表是合二為一的 所有 有關 PMD 的操作實際上是對 PGD 的操作 所以原代碼中形如 pgd 和 pmd 的函數(shù) 實現(xiàn)的功能也是一樣的 頁目錄 PGD 是一個大小為 4K 的表 每一個 process 只有一個頁目錄 以 4 字節(jié)為 一個表項 分成 1024 個表項 或稱入口點 該表項的值為所指頁表的始地址 32 位虛擬 地址的第 1 個子位段共 10 位 其值的范圍從 0 到 1023 對應于頁目錄的一個入口點 頁目錄 PTE 的每一個入口點的值為此表項所指的一頁框 page frame 32 位虛擬 地址的第 2 個子位段共 10 位 其值的范圍從 0 到 1023 頁框 page frame 并不是物理頁 它指是虛存的一個地址空間 3 頁表項的格式 頁表項的格式 Linux 中頁表每一個表項的格式 如圖所示 31 12 11 7 6 5 4 3 2 1 0 Address Reserved DA U RP SW 圖 3 頁表項格式 其中 各位段的含義如下 P 存在位 表示該表項對地址的轉換是否有效 i386 處理器在 P 0 時不解釋 表項中的任何位 此時這些位的含義完全由軟件自行解釋 P 位提供了至關 重要的屬性 以支持分頁機制 如果 P 1 則表示虛擬地址所對應的頁框存 在于物理內存中 訪問該虛擬地址的程序可以正常運行 P 0 則表示虛擬 地址所對應的頁框不存在于物理內存中 訪問該虛擬地址的程序將會引發(fā)頁 訪問異常 產(chǎn)生缺頁中斷 使得 Operating System 可以把缺少的頁從磁盤上 讀入內存 并將讀入頁存入到表項中 然后將該頁標志為存在 再使引起異 常的程序繼續(xù)執(zhí)行 R W 讀寫位 表示對該表項指向的頁可以進行讀 寫或執(zhí)行操作 R W 1 則該頁 可寫 可讀 且可執(zhí)行 R W 0 則該頁可讀 可執(zhí)行 但不可寫 當處理器 處于特權級 0 2 時 R W 位被忽略 如該表項位于頁目錄中 則作用于該表 項映射的所有各頁 U S 用戶 系統(tǒng)位 U S 1 則該頁可在任何處理器特權級下訪問 U S 0 則該頁只 能在處理器特權級 0 2 下被訪問 如該表項位于頁目錄中 則作用于該表項 映射的所有各頁 D 已寫標志位 在對該表項映射的頁進行寫訪問之前 處理器對該位置 1 如 該表項是頁目錄中表項 處理器不修改 D 位 Address 頁框物理地址的高 20 位 系統(tǒng)將物理內存分割成 4K 大小的內存頁框 Address 實際上代表了頁框的幀號 4 動態(tài)地址映射 動態(tài)地址映射 Linus 虛存采用動態(tài)地址映射方式 即 Process 的地址空間和存儲空間的對應關系是在 程序的執(zhí)行過程中實現(xiàn)的 Process 每用到一個地址時 都需虛存的地址轉換機構把虛擬 地址轉化為內存的實際地址 其地址映射如下圖所示 圖 4 32 位虛擬地址轉換圖 動態(tài)地址映射使 Linux 可以實現(xiàn) Process 在主存中的動態(tài)重定位 虛存段的動態(tài)擴展和 移動 也為虛存的實現(xiàn)提供了基礎 5 用戶進程的虛擬內存結構 用戶進程的虛擬內存結構 用戶進程的虛擬內存結構如圖所示 mm struct 每一個進程的 task struct 中都有一個結構 mm struct 此結構包含了進程中與儲存管理 相關的大部分信息 其申明如下 struct mm struct int count 使用該 mm 結構的個數(shù) 如果是多處理機 則有可能 count 1 pgd t pgd 進程頁目錄的起始地址 如上圖所示 unsigned long context unsigned long start code end code start data end data start code end code 進程代碼段的起始地址和結束地址 start data end data 進程數(shù)據(jù)段的起始地址和結束地址 unsigned long start brk brk start stack start mmap unsigned long arg start arg end env start env end arg start arg end 調用參數(shù)區(qū)的起始地址和結束地址 env start env end 進程環(huán)境區(qū)的起始地址和結束地址 unsigned long rss total vm locked vm rss 進程內容駐留在物理內存的頁面總數(shù) unsigned long def flags struct vm area struct mmap 以雙向鏈表組成的 vma 模塊的首指針 struct vm area struct mmap avl 以 avl 樹結構組成的虛擬空間的首指針 struct semaphore mmap sem 用戶進程虛存管理的數(shù)據(jù)結構如圖 5 所示 用戶共有 4GB 的虛存空間 實際可申請 的虛存空間為 0 3GB 3GB 4GB 的虛存空間在用戶進程創(chuàng)建時 已由函數(shù) fork 將 kernel 的代碼段和數(shù)據(jù)段映射到 3GB 4GB 的虛存空間 因而所有進程的 3GB 4GB 的虛存空間 的映象都是相同的 從而以這種方式使所有進程共享 kernel 的代碼段和數(shù)據(jù)段 VMA 進程的虛擬空間通常由一個個 vma 塊組成 這些塊的結構如下所示 struct vm area struct struct mm struct vm mm VM area parameters unsigned long vm start 該 vma 塊代表的使用虛擬空間的起始地址 unsigned long vm end 該 vma 塊代表的使用虛擬空間的結束地址 pgprot t vm page prot 保護位 unsigned short vm flags 標志位 AVL tree of VM areas per task sorted by address short vm avl height avl 樹高度 struct vm area struct vm avl left vma 塊的左子節(jié)點 struct vm area struct vm avl right vma 塊的右子節(jié)點 linked list of VM areas per task sorted by address struct vm area struct vm next 在按地址大小排列的單向鏈表 上的下一個指針 for areas with inode the circular list inode i mmap for shm areas the circular list of attaches otherwise unused struct vm area struct vm next share struct vm area struct vm prev share more struct vm operations struct vm ops 對 VMA 塊進行操作的函數(shù)集 unsigned long vm offset struct inode vm inode 該 VMA 塊對應的文件 unsigned long vm pte shared mem 采用 avl 樹的優(yōu)點是可以快速找到相關地址所在的 vma 塊 同時 同一個任務的 vma 塊還按前后順序排成一個線性鏈表 6 我們的工作 我們的工作 針對上圖所示的用戶進程虛存管理的數(shù)據(jù)結構 圍繞它的建立 維護 使用和拆除 我們組作了相應的工作 主要包括以下幾點 1 進程的載入 創(chuàng)建及內存管理數(shù)據(jù)結構和鏈結關系的建立 sys execve sys fork sys clone 2 頁表的建立與釋放 new page tables free page tables 3 虛擬內存的申請與釋放 sys mmap sys munmap 4 缺頁中斷處理 do page fault 5 虛擬塊 VMA 的管理 sys remap sys mprotect 6 數(shù)據(jù)結構及鏈結關系的拆除 sys exit 其中 虛擬內存的申請與釋放由林濤和徐玫峰同學負責 虛擬塊 VMA 的管理由范昭 偉同學負責 相關的工作體現(xiàn)在他們的分析報告中 第四章第四章 Process 的虛存管理數(shù)據(jù)結構的建立 維護 的虛存管理數(shù)據(jù)結構的建立 維護 拆除及相關系統(tǒng)調用流程拆除及相關系統(tǒng)調用流程 1 進程的載入 創(chuàng)建及內存管理數(shù)據(jù)結構和鏈結關系的建立 進程的載入 創(chuàng)建及內存管理數(shù)據(jù)結構和鏈結關系的建立 sys execve 系統(tǒng)調用負責將可執(zhí)行文件映象載入到內存 與內存相關的操作主要是 通過調用 exit mmap 清除當前進程的所有的虛存塊 通過調用 clear page table 清除當前進 程的頁表項 通過調用 flush old signals 清除當前進程的殘留信號 通過調用 flush old files 清除當前進程的已打開文件 從而將當前進程掏空 成為一個空殼 然后系 統(tǒng)根據(jù) bprm 結構更新 current 進程的控制塊 并通過調用兩次 do mmap 分別將執(zhí)行文件的 代碼段和數(shù)據(jù)段映射到虛存 系統(tǒng)一般只將前兩頁載入物理內存中 同時分配一頁給堆棧 其它的均留在硬盤中通過虛擬內存映射機制映射為虛擬內存 當運行中發(fā)生缺頁中斷時 系統(tǒng)處理缺頁中斷 將缺頁調入物理內存中 如果發(fā)生物理內存不足的情況 則由 kswapd 選擇合適的頁調入交換文件中或扔掉 如未發(fā)生寫操作 具體流程如下 asmlinkage int sys execve struct pt regs regs 為 do execve 的調用準備參數(shù) do execve 初始化 bprm bprm 是 struct linux binprm 進程控制塊中某些參數(shù)的暫存器 search binary handler 尋找二進制文件的處理程序 handler 并用該 handler 一般是 load aout binary 程序處理該二進制文件 load aout binary do load aout binary 異常情況判斷 flush old exec bprm exec mmap if necessary then copy on write exit mmap current mm 清除當前進程的所有的虛存塊 clear page table current 清除當前進程的頁表項 flush tlb mm current mm flush thread flush old signals current sig 清除當前進程的殘留信號 flush old files current files 清除當前進程的已打開文件 到此為止 當前進程已被掏空 成為一個空殼 根據(jù) bprm 結構更新 current 進程的控制塊 do mmap 將執(zhí)行文件的代碼段映射到虛存 do mmap 將執(zhí)行文件的數(shù)據(jù)段映射到虛存 do load aout binary end for load aout binary end for search binary handler end for do execve end for sys execve 2 do fork 當通過 sys fork 和 sys clone 系統(tǒng)調用來創(chuàng)建子進程時 系統(tǒng)將通過 do fork 函數(shù)來完 成大部分的創(chuàng)建任務 do fork 函數(shù)首先申請一頁的核心空間給進程控制塊 再申請一頁的 核心空間給系統(tǒng)堆棧 再通過 copy mm 函數(shù)為子進程復制父進程的虛擬空間 如果是 sys clone 系統(tǒng)調用 則不用復制 子進程的 mm 指針指向父進程 mm struct 具體流程如 下 asmlinkage int sys fork struct pt regs regs return do fork SIGCHLD regs esp asmlinkage int sys clone struct pt regs regs unsigned long clone flags unsigned long newsp clone flags regs ebx newsp regs ecx if newsp newsp regs esp return do fork clone flags newsp do fork 申請一頁的核心空間給進程控制塊 struct task struct p 申請一頁的核心空間給系統(tǒng)堆棧 P current 復制父進程的進程控制塊 作必要的修改 copy mm 如果是 clone 父子進程的 mm 指針指向同一個 mm struct mm struct count else 畫圖 struct mm struct mm 申請一頁核心空間 mm current mm 復制父進程的相關信息 new page tables 建立新的頁目錄表 pgd 且復制 init 進程的 768 1023 項 dup mmap 復制父進程的虛擬空間映射 for 對于父進程中的每一個 VMA 塊 復制該 VMA 塊 作相應修改并重新鏈起來 copy page range mm current mm 該 VMA 塊 其工作機制是循環(huán)調用 copy pmd range 將 vma 塊中的所有 虛擬空間復制到對應的虛擬空間中 在做復制之前 必須確保 新任務對應的被復制的虛擬空間中必須都為零 end for dup mmap end for copy mm end for do fork 2 數(shù)據(jù)結構及鏈結關系的拆除 數(shù)據(jù)結構及鏈結關系的拆除 sys exit sys exit 系統(tǒng)調用 sys exit 來結束進程 調用 exit mm 將所有虛擬內存都結束掉 最后中止進 程 asmlinkage int sys exit int error code do exit kerneld exit exit mm current if current mm count 無其他進程共享該 mm struct exit mmap mm for 對于當前進程 current mm 中的每一個 VMA 塊 調用 vm ops unmap 釋放該 VMA 塊對應的虛擬空間 調用 zap page range 將指向釋放掉的虛擬空間中的 pte 頁表項 清零 調用 kfree 釋放該 VMA 塊結構占用的物理空間 free page tables mm 將 mm pdg 中所有的 pte 頁表項清空 并將 mm pdg 清空 kfree mm current mm init mm end for exit mm current exit files current exit fs current exit sighand current end for do exit 3 缺頁中斷服務 缺頁中斷服務 當程序在運行中 訪問到的無效的虛擬地址的時候 系統(tǒng)將激發(fā)出缺頁中斷 激發(fā)缺頁中斷的情況通常有四種 1 C O W 型中斷 當某個進程進行寫操作時 如果寫的頁是多進程在使用 時 為了不影響其它進程的正常運行 通常需要將該頁復制一份 供執(zhí)行寫 操作的進程單獨使用 2 被訪問的物理頁由于太長時間沒有訪問而被 kswapd 置換到 swap file 中 3 被訪問的物理頁由于是第一次訪問 所以還在磁盤上或由于訪問后被置換時 因為沒有發(fā)生寫操作 而未寫到 swap file 中 4 當進程動態(tài)的訪問一片存儲區(qū)域時 如在程序中動態(tài)開辟的數(shù)組等 則該頁 不在 swap file 中 也不在磁盤上 缺頁中斷服務入口程序是函數(shù) do page fault do page fault 首先進行各種錯誤情況判斷 并作相應處理 然后根據(jù) error code 來判斷缺頁中斷類型 第一種情況采用 do wp page 函數(shù)來處理 第二 三 四種情況由 do no page 函數(shù)來處理 下面將分別介紹這些函數(shù)的流程圖 void do wp page struct task struct tsk struct vm area struct vma unsigned long address int write access 為復制可寫頁申請一頁空間 根據(jù) address 計算 pgd pmd pte 退出 使用該物理頁的進程 1 將該物理頁置 dirty 釋放原先分配的復制頁 將物理頁復制到復制頁上 將復制頁鏈入虛存中 將指向原先物理頁的 pte 釋放掉退出 異常 1 1 圖 7 do wp page 示意圖 void do no page struct task struct tsk struct vm area struct vma unsigned long address int write access 根據(jù) address 計算三級頁表中 pgd pmd pte 的值 如無對應的項 分配空間將 其填上 if pte present entry 該頁已在內存中 return 可能是共享該頁的其他進程已將該頁讀入 else if pte none entry 情況 2 pte 中該項非空 說明該頁被 kswapd 置換到 swap file 中 調用 do swap page 讀入該頁 else if vma vm ops vma vm ops nopage 情況 4 該頁對應的 VMA 塊沒有相應的 nopage 操作 說明該 VMA 塊對應的是 數(shù)據(jù)段內容 調用 get free page 操作為該頁分配內存 并將該頁賦值為 0 同時鏈入 該進程的頁表中 else 情況 3 調用虛擬塊操作將磁盤中對應文件讀入 page 中 將 pte 表中對應的項指向該頁 將該頁 dirty 位置位 如果該頁有多進程使用 且非共享 置寫保護位 第五章第五章 主要函數(shù)分析主要函數(shù)分析 Memory c 在該文件中 Linux 提供了對虛擬內存操作的若干函數(shù) 其中包括對虛擬頁的復制 新建頁表 清除頁表 處理缺頁中斷等等 1 static inline void copy page unsigned long from unsigned long to 為了節(jié)約內存的使用 在系統(tǒng)中 各進程通常采用共享內存 即不同的進程可以共享 同一段代碼段或數(shù)據(jù)段 當某一進程發(fā)生對共享的內存發(fā)生寫操作時 為了不影響其它進 程的正常運行 系統(tǒng)將把該內存塊復制一份 供需要寫操作的進程使用 這就是所謂的 copy on write 機制 copy page 就是提供復制內存功能的函數(shù) 它調用 C 語言中標準的內 存操作函數(shù) 將首地址為 from 的一塊虛擬內存頁復制到首地址為 to 的空間中 2 void clear page tables struct task struct tsk clear page table 的功能是將傳入的結構 tsk 中的 pgd 頁表中的所有項都清零 同時將 二級頁表所占的空間都釋放掉 傳入 clear page tables 的是當前進程的 tsk 結構 取得該進 程的一級頁目錄指針 pgd 后 采用循環(huán)的方式 調用 free one pgd 清除 pgd 表 表共 1024 項 在 free one pgd 中 實際執(zhí)行的功能只調用一次 free one pmd 在 80 x86 中 由于硬 件的限制 只有兩級地址映射 故將 pmd 與 pgd 合并在一起 在 free one pmd 中 函數(shù) 調用 pte free 將對應于 pmd 的二級頁表所占的物理空間釋放掉 進程代碼 數(shù)據(jù)所用的物 理內存在 do munmap 釋放掉了 并將 pmd 賦值為零 clear page table 在系統(tǒng)啟動一個可執(zhí)行文件的映象或載入一個動態(tài)鏈接庫時被調用 在 fs exec c 中的 do load elf binary 或 do load aout binary 調用 flash old exec 后者調 用 exec mmap 而 exec mmap 調用 clear page table 其主要功能是當啟動一個新的應用 程序的時候 將復制的 mm struct 中的頁表清除干凈 并釋放掉原有的所有二級頁表空間 3 void oom struct task struct task 返回出錯信息 4 void free page tables struct mm struct mm 在 free page table 中 大部分的代碼與 clear page table 中的函數(shù)一致 所不同的是 該函數(shù)在最后調用了 pgd free page dir 即不光釋放掉二級頁表所占的空間 同時還釋放 一級頁目錄所占的空間 這是因為 free page tables 被 exit mm 調用 exit mm 又被 do exit kernel kernel c 調用 當進程中止 系統(tǒng)退出或系統(tǒng)重起時都需要用 do exit 屬于進程管理 將所有的進程結束掉 在結束進程過程中 將調用 free page table 將進程的空間全部釋放掉 當然包括釋放進程一級頁目錄所占的空間 5 int new page tables struct task struct tsk 該函數(shù)的主要功能是建立新的頁目錄表 它的主要流程如如下 1 調用 pgd alloc 為新的頁目錄表申請一片 4K 空間 2 將初始化進程的內存結構中從 768 項開始到 1023 項的內容復制給新的頁表 所 有的進程都共用虛擬空間中 3G 4G 的內存 即在核心態(tài)時可以訪問所有相同的 存儲空間 3 調用宏 SET PAGE DIR include asm pgtable h 將進程控制塊 tsk ts CR3 的值 改為新的頁目錄表的首地址 同時將 CPU 中的 CR3 寄存器的值改為新的頁目錄 表的首地址 從而使新進程進入自己的運行空間 4 將 tsk mm pgd 改為新的頁目錄表的首地址 new page tables 被 copy mm 調用 而 copy mm 被 copy mm do fork 調用 這兩個函 數(shù)都在 kernel fork c 中 同時 new page tables 也可以在 exec mmap fs exec c 中調用 即新的進程的產(chǎn)生可以通過兩種途徑 一種是 fork 在程序中動態(tài)地生成新的進程 這樣 新進程的頁表原始信息利用 copy mm 從其父進程中繼承而得 另一種是運行一個可執(zhí)行 文件映象 通過文件系統(tǒng)中的 exec c 將映象復制到 tsk 結構中 兩種方法都需要調用 new page tables 為新進程分配頁目錄表 6 static inline void copy one pte pte t old pte pte t new pte int cow 將原 pte 頁表項復制到 new pte 上 其流程如下 1 檢測 old pte 是否在內存中 如不在物理內存中 調用 swap duplicate 按 old pte 在 swap file 中的入口地址 將 old pte 復制到內存中 同時把 old pte 的入口地址 賦給 new pte 并返回 反之轉向 3 2 獲取 old pte 對應的物理地址的頁號 3 根據(jù)頁號判斷 old pte 是否為系統(tǒng)保留的 如果為系統(tǒng)保留的 這些頁為所有的 進程在核心態(tài)下使用 用戶進程沒有寫的權利 則只需將 old pte 指針直接轉賦 給 new pte 后返回 反之則該 pte 屬于普通內存的 則轉向 4 4 根據(jù)傳入的 C O W 標志 為 old pte 置寫保護標志 如果該頁是從 swap cache 中 得來的 將 old pte 頁置上 dirty 標志 將 old pte 賦值給 new pte 5 將 mem map 結構中關于物理內存使用進程的個數(shù)的數(shù)值 count 加 1 7 static inline int copy pte range pmd t dst pmd pmd t src pmd unsigned long address unsigned long size int cow 通過循環(huán)調用 copy one pte 將從源 src pmd 中以地址 address 開始的長度為 size 的空 間復制給 dst pmd 中 如 dst pmd 中還未分配地址為 address 的頁表項 則先給三級頁表 pte 表分配 4K 空間 每調用一次 copy one pte 復制 4K 空間 在一次 copy pte range 中最 多可復制 4M 空間 8 static inline int copy pmd range pgd t dst pgd pgd t src pgd unsigned long address unsigned long size int cow 通過循環(huán)調用 copy pte range 將從源 src pgd 中以地址 address 開始的長度為 size 的空 間復制給 dst pgd 中 如 dst pgd 中還未分配地址為 address 的頁表項 則在一級 同時也 是二級 頁表中給對應的 pmd 分配目錄項 9 int copy page range struct mm struct dst struct mm struct src struct vm area struct vma 該函數(shù)的主要功能是將某個任務或進程的 vma 塊復制給另一個任務或進程 其工作機 制是循環(huán)調用 copy pmd range 將 vma 塊中的所有虛擬空間復制到對應的虛擬空間中 在 做復制之前 必須確保新任務對應的被復制的虛擬空間中必須都為零 copy page range 按 dup mmap copy mm do fork 的順序被調用 以上三個函數(shù)均在 kernel fork c 中 當進程被創(chuàng)建的時候 需要從父進程處復制所有的虛擬空間 copy page range 完成的就是 這個任務 copy page range 的函數(shù)調用關系見圖 8 copy page range copy pmd range copy pte range copy one pte dup mmap copy mm do fork kernel fork c 圖 8 copy page range 示意圖 9 static inline void free pte pte t page 虛存頁 page 如在內存中 且不為系統(tǒng)的保留內存 調用 free page 將其釋放掉 如在 系統(tǒng)保留區(qū)中 則為全系統(tǒng)共享 故不能刪除 如 page 在 swap file 中 調用 swap free 將其釋放 10 static inline void forget pte pte t page 如 page 不為空 調用 free pte 將其釋放 11 static inline void zap pte range pmd t pmd unsigned long address unsigned long size zap 為 zero all pages 的縮寫 該函數(shù)的作用是將在 pmd 中從虛擬地址 address 開始 長度為 size 的內存塊通過循環(huán)調用 pte clear 將其頁表項清零 調用 free pte 將所含空間中 的物理內存或交換空間中的虛存頁釋放掉 在釋放之前 必須檢查從 address 開始長度為 size 的內存塊有無越過 PMD SIZE 溢出則可使指針逃出 0 1023 的區(qū)間 12 static inline void zap pmd range pgd t dir unsigned long address unsigned long size 函數(shù)結構與 zap pte range 類似 通過調用 zap pte range 完成對所有落在 address 到 address size 區(qū)間中的所有 pte 的清零工作 zap pmd range 至多清除 4M 空間的物理內存 13 int zap page range struct mm struct mm unsigned long address unsigned long size 函數(shù)結構與前兩個函數(shù)類似 將任務從 address 開始到 address size 長度內的所有對應 的 pmd 都清零 zap page range 的調用關系與被調用的關系如圖 9 可知 zap page range 的主要功能是在進行內存收縮 釋放內存 退出虛存映射或移動頁表的過程中 將不在使 用的物理內存從進程的三級頁表中清除 在討論 clear page tables 時 就提到過當進程退 出時 釋放頁表之前 先保證將頁表對應項清零 保證在處于退出狀態(tài)時 進程不占用 0 3G 的空間 zap page rangevm truncate do munmap exit mmap move page tables zap pmd range zap pte range free page 圖 9 zap page range 調用關系示意圖 14 static inline void zeromap pte range pte t pte unsigned long address unsigned long size pte t zero pte 15 static inline int zeromap pmd range pmd t pmd unsigned long address unsigned long size pte t zero pte 16 int zeromap page range unsigned long address unsigned long size pgprot t prot 這三個函數(shù)與前面的三個函數(shù)從結構上看很相似 他們的功能是將虛擬空間中從地址 address 開始 長度為 size 的內存塊所對應的物理內存都釋放掉 同時將指向這些區(qū)域的 pte 都指向系統(tǒng)中專門開出的長度為 4K 全為 0 的物理頁 zeromap page range 在 kernel 代碼中沒有被引用 這個函數(shù)是舊版本的 Linux 遺留下來的 在新版本中已經(jīng)被 zap page range 所替代 17 static inline void remap pte range pte t pte unsigned long address unsigned long size unsigned long offset pgprot t prot 18 static inline int remap pmd range pmd t pmd unsigned long address unsigned long size unsigned long offset pgprot t prot 19 int remap page range unsigned long from unsigned long offset unsigned long size pgprot t prot 這三個函數(shù)也同前面的函數(shù)一樣 層層調用 現(xiàn)僅介紹一下最后一個函數(shù)的作用 remap page range 的功能是將原先被映射到虛擬內存地址 from 處的 大小為 size 的虛擬內 存塊映射到以偏移量 offset 為起始地址的虛擬內存中 同時將原來的 pte pmd 項都清零 該函數(shù)也是逐級調用 在 remap pte range 中 通過 set pte 將的物理頁映射到新的虛擬內 存頁表項 pte 上 remap page range 函數(shù)的功能與下文中的 remap c 中介紹的功能相近 因 此在 kernel 中也沒有用到 20 unsigned long put dirty page struct task struct tsk unsigned long page unsigned long address 將虛擬內存頁 page 鏈接到任務 tsk 中虛擬地址為 address 的虛擬內存中 其主要調用 的流程如下 put dirty page setup arg page do load xxx binary xxx 為 aout 或 elf 這些 函數(shù)都在 fs exec c 中 它的功能是將在載入可執(zhí)行文件的時候 將其相關的堆棧信息 環(huán) 境變量等復制到當前進程的空間上 21 void handle mm fault struct vm area struct vma unsigned long address int write access 用于處理 ALPHA 機中的缺頁中斷 mmap c 在 mmap c 中 主要提供了對進程內存管理進行支持的函數(shù) 主要包括了 do mmap do munmap 等對進程的虛擬塊堆 avl 數(shù)進行管理的函數(shù) 圖 10 mmap c 中函數(shù)調用圖 有關有關 avl 樹的一些操作 樹的一些操作 1 static inline void avl neighbours struct vm area struct node struct vm area struct tree struct vm area struct to the left struct vm area struct to the right 尋找 avl 樹 tree 中的節(jié)點 node 的前序節(jié)點和后序節(jié)點 將結果放在指針 to the left 和 to the right 中 即使得 to the left next node node next to the right 在實際搜索中 過程是找到 node 節(jié)點中的左節(jié)點的最右節(jié)點和右節(jié)點的最左節(jié)點 采用 avl 樹搜索可以提 高效率 2 static inline void avl rebalance struct vm area struct nodeplaces ptr int count 將由于插入操作或刪除操作而造成不平衡的 avl 樹恢復成平衡狀態(tài) nodeplaces ptr 是 指向的是需要調整的子樹的根節(jié)點 count 是該子樹的高度 3 static inline void avl insert struct vm area struct new node struct vm area struct ptree 將新節(jié)點 new node 插入 avl 樹 ptree 中 并將該樹重新生成平衡 avl 樹 在創(chuàng)建 avl 樹 時 將 vma 模塊不斷的插入 avl 樹中 構建一個大的 avl 樹 當進程創(chuàng)建時 復制父進程 后需要將以雙向鏈表拷貝過來的 vma 鏈生成 avl 樹 4 static inline void avl insert neighbours struct vm area struct new node struct vm area struct ptree struct vm area struct to the left struct vm area struct to the right 將新節(jié)點 new node 插入 avl 樹 ptree 中 并將該樹重新生成平衡 avl 樹 同時返回該 新節(jié)點的前序節(jié)點和后序節(jié)點 avl rebalance avl insertavl insert neighbouravl neighbouravl remove build mmap avl dup mmap copy mm forkdo munmap merge segments unmap fixup insert vm struct do mmap 5 static inline void avl remove struct vm area struct node to delete struct vm are

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論