歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

讀核日記 ( 七 )

作者: sunmoon     內存管理是一個操作系統必不可少.並且.非常重要的一環.Linux的成功.和它優秀的內存管理聯系   非常密切.因為一個系統的高效性欲穩定性往往決定於它的內存管理機制.我項很多人吃過dos下   640k 的苦吧.     前面我們介紹了386保護模式.從今天起我們將在此基礎上,分析linux的虛擬存儲管理,對每個程序   員來說.他們都希望有無窮大的快速的內存,然而,現階段是不可能的,況且,無窮大與快速本身就可   能矛盾     為了解決無窮大.linux 引入了虛擬存儲系統,為了解決快速,linux 引入了cache ,交換機制等等,   以使的存儲系統,在容量上接近硬盤,速度上接近cache.(當然,我認為這是存儲系統的實際目的).     Linux 的內存管理采取的是分頁機制.它的設計目的是分時多任務.linux 可同時處理256個任務   (這應該與某個變量來定義,一時想不起來).同時它采用了兩級飽和機制來分別內核進程與用戶進程.     在386 保護模式的0-4G 的線性虛擬地址中,3-4G 是留給內核進程的.而0-3G分給用戶進程.內核在   內核空間的尋址不同於用戶進程在用戶空間的尋址.因為內核是在啟動時裝入內存的.說以它可以   直接吧地址映射到3G 以上.用戶若想訪問內核就不許通過swapper_pg_div 中的指針來得到頁表.     相反,用戶進程,在用戶空間的尋址是通過所用戶頁目錄中的指針得到用戶的頁表.並通過頁表的指   針直接指向相應的物理內存.     Linux虛擬內存的實現,需要幾種不同的機制來實現:     地址映射機制     內存的分配與回收     請頁機制     交換機制     內存共享機制     在具體的讀源碼之前.我們先根據我們以前學過的操作系統知識.和C語言等知識.來考慮一下,這幾   個機制如何實現.現自己設計一下.在看別人是怎樣實現的.找到自己想不到.或者對效率空間有損   的地方.這樣才有進步.我不止一次的說.操作系統的某一部分,就起實現來說,非常簡單.它的難點   是如何將大量的功能集成出一個kernerl.     地址映射機制,說白了,就是在虛擬內存與物理內存上的一個橋梁.它要做的事情可能就是通過幾個   不同的表.把虛擬地址轉換成物理地址,把物理地址轉化虛擬地址.     我們以前說過.因為有系統與用戶之分,它必須也要有不同的數據結構.為了解決速度等問題.它會   有一個硬件的緩沖區     對於它的數據結構.我們可以先想一下.如虛擬地址的信息,虛擬地址在那個區域等等     至於請頁機制,更好理解.因為linux是頁式存儲的.因此必然會存在空白頁和使用頁.既然是頁.就   必然會存在頁溢出.頁無效(是不是在win98 下經常出現類似錯誤,當然linux的內存管理不可能和   windows一樣,可基本道理相同).因此.在每一個頁出錯.或者該頁存不下多余的數據時.就要要求內   核分配新的頁面     同時.當時用fork() 產生一個新的進程時.也需要分配新的葉面.這一部分大概講的就是進程如何   向內和描述自己需要怎麼樣的和多少頁     在我們學習<<數據結構>>是我們學了,很多內存分配方式,如首次擬和.最佳擬和,最差擬和等等.但   是我們可以想象.linux 大概不會用他們.那就一定是伙伴系統了.因此我們可以對於伙伴系統的分   配,回收的基本算法.回想一下.這樣在讀者一部分源碼時,回有意象不到的收獲.     至於交換機制.我們也可以現想一想.內存中總與很多使用者的頁.如果這些也已經把所有的頁都用   完了.再分配時必須把其中的某些頁釋放.釋放那些頁,需要考慮.如最近不用頁.近期少用頁,等等   都可以在考慮之中.     這個算法,大概就是計算內存中使用的頁,什麼時候可以換處.說白了就是為所有的使用頁計算一   個”權”,而這個”權”就決定了他什麼時候被釋放以換如它的內容.需要想的是對於經常使用的頁.可   以把它放入cahe.(盡管這一部分對程序員是透明的,但我們應該理解他的原理).     最後的一部分共享內存,我想和我門初學linux編程時,進程通訊裡面的共享內存沒有區別.大概也   就是在它的數據結構中加入可以允許不同進程訪問的tag 就行了.     以上,只是我們對linux的內存管理機制的猜測,需要我們做的工作就是具體的讀源碼.更正不正確   的猜想.同時學習別人的實際思路.         地址的映射機制     地址的映射機制,主要完成主存.輔存.和虛存之間的關聯.包括磁盤文件到虛存的映射和虛存與內   存的映射關系.為了虛擬存儲和進程調度相一致.linux 采用可一系列的數據結構,和一個硬件緩存   (TLB)來實現地址映射機制.     mm_strut 用來描述進程的緩存.     strUCt mm_struct     {     struct vm_area_struct * mmap; /* list of VMAs */     struct vm_area_struct * mmap_avl; /* tree of VMAs */     struct vm_area_struct * mmap_cache; /* last find_vma result */     pgd_t * pgd;     atomic_t count;     int map_count; /* number of VMAs */     struct semaphore mmap_sem;     spinlock_t page_table_lock;     unsigned long context;     unsigned long start_code, end_code, start_data, end_data;     unsigned long start_brk, brk, start_stack;     unsigned long arg_start, arg_end, env_start, env_end;     unsigned long rss, total_vm, locked_vm;     unsigned long def_flags;     unsigned long cpu_vm_mask;     unsigned long swap_cnt; /* number of pages to swap on next pass */     unsigned long swap_address;     /*     * This is an architecture-specific pointer: the portable     * part of Linux does not know about any segments.     */     void * segments;     };     他描述了一個進程的頁目錄,有關進程的上下文信息.以及數據.代碼.堆棧的啟示結束地址.還有虛   擬存儲取得數目.以及調度存儲用的鏈表指針.他的參差比較高     較高層次的vm_area-struct 是描述進程的虛擬地址區域.他形成一個算相鏈表.按虛地址下降排列   .這樣當內核需要在一個給定進程頁上執行給定操作時.客從雙向列表中找到該項.在世想有關頁的   處理.如.頁錯誤.頁換出等等     他的具體結構如下:     struct vm_area_struct {     struct mm_struct * vm_mm; /* VM area parameters */     unsigned long vm_start;     unsigned long vm_end;           /* linked list of VM areas per task, sorted by address */     struct vm_area_struct *vm_next;           pgprot_t vm_page_prot;     unsigned short vm_flags;           /* AVL tree of VM areas per task, sorted by address */     short vm_avl_height;     struct vm_area_struct * vm_avl_left;     struct vm_area_struct * vm_avl_right;           /* For areas with inode, the list inode->i_mmap, for shm areas,     * the list of attaches, otherwise unused.     */     struct vm_area_struct *vm_next_share;     struct vm_area_struct **vm_pprev_share;           struct vm_operations_struct * vm_ops;     unsigned long vm_offset;     struct file * vm_file;     unsigned long vm_pte; /* shared mem */     };     而page 結構 則是對物理頁進行描述的一個數據結構,他不是一個真正的物理頁.而只不過是描述   了一個物理頁的內容和框架.作了邏輯頁的一個標志;.他的標志域定義了這個頁在進行的操作.鏈   域則定義了一個雙項鏈表.時的頁框.可以很容易的查找到.為實際物理內存的使用直到方便     他的具體結構如下     typedef struct page {     /* these must be first (free area handling) */     struct page *next;     struct page *prev;     struct inode *inode;     unsigned long offset;     struct page *next_hash;     atomic_t count;     unsigned long flags; /* atomic flags, some possibly updated asynchronously */     wait_queue_head_t wait;     struct page **pprev_hash;     struct buffer_head * buffers;     int owner; /* temporary debugging check */     } mem_map_t;     所有的page 結構將都被轉入一個叫做mem_map 的數組中.     當一個進程運行時,他的代碼段和數據段將都會被調入內存.如果它使用了共享庫.共享客的內容也   將貝雕如內存.進程運行時.系統首先分配一個vm_area_struct 給進程.並將這各進程連結到虛擬   內存的連標中去.這是根據進程的可執行影像中的信息.吧數據段和客執行代碼非配內存.新分配的   內存必須和進程已有的內存連結起來才能應用.這樣聚會出現頁故障.系統利用了請頁機制來避免   對物理內存的過分使用.但進程訪問的虛存不在當前的物理內存時,這時系統會將需要的頁調入內   存.同時修改進程的頁表.用來標志虛擬頁是否在物理內存中.     因此,系統用了較復雜的數據結構來跟蹤進程的虛擬地址.在task_struct 中包含一個指向   mm_struct 結構的指針.進程的mm_struct 中則包含了進程可執行影像的頁目錄指針pgd.還包含了   指向vm_area_struct 的幾個指針,每個vm_area_struct 包含一個進程的虛擬地址區域.     一個進程有多個vm_area_stuct 結構.linux 要經常對進程分配..或調整vm_area_struct .這樣對   vm_area_stuct 的查找效率.對系統很有影像.所以在這裡將所有的vm_area_struct 形成了一個查   找效率較高的平衡二叉樹結構.     我個人認為,在整個linux內核中這個地方.數據結構是最復雜的.如果把這一部分肯下來以後,整個   內核便開始清晰了




 



Copyright © Linux教程網 All Rights Reserved