国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

讀核日記 ( 七 )

2024-07-21 02:38:23
字體:
供稿:網(wǎng)友

  作者: sunmoon
  
  內(nèi)存治理是一個操作系統(tǒng)必不可少.并且.非常重要的一環(huán).linux的成功.和它優(yōu)秀的內(nèi)存治理聯(lián)系
  非常密切.因為一個系統(tǒng)的高效性欲穩(wěn)定性往往決定于它的內(nèi)存治理機制.我項很多人吃過dos下
  640k 的苦吧.
  
  前面我們介紹了386保護模式.從今天起我們將在此基礎(chǔ)上,分析linux的虛擬存儲治理,對每個程序
  員來說.他們都希望有無窮大的快速的內(nèi)存,然而,現(xiàn)階段是不可能的,況且,無窮大與快速本身就可
  能矛盾
  
  為了解決無窮大.linux 引入了虛擬存儲系統(tǒng),為了解決快速,linux 引入了cache ,交換機制等等,
  以使的存儲系統(tǒng),在容量上接近硬盤,速度上接近cache.(當(dāng)然,我認為這是存儲系統(tǒng)的實際目的).
  
  Linux 的內(nèi)存治理采取的是分頁機制.它的設(shè)計目的是分時多任務(wù).linux 可同時處理256個任務(wù)
  (這應(yīng)該與某個變量來定義,一時想不起來).同時它采用了兩級飽和機制來分別內(nèi)核進程與用戶進程.
  
  在386 保護模式的0-4G 的線性虛擬地址中,3-4G 是留給內(nèi)核進程的.而0-3G分給用戶進程.內(nèi)核在
  內(nèi)核空間的尋址不同于用戶進程在用戶空間的尋址.因為內(nèi)核是在啟動時裝入內(nèi)存的.說以它可以
  直接吧地址映射到3G 以上.用戶若想訪問內(nèi)核就不許通過swapper_pg_div 中的指針來得到頁表.
  
  相反,用戶進程,在用戶空間的尋址是通過所用戶頁目錄中的指針得到用戶的頁表.并通過頁表的指
  針直接指向相應(yīng)的物理內(nèi)存.
  
  Linux虛擬內(nèi)存的實現(xiàn),需要幾種不同的機制來實現(xiàn):
  
  地址映射機制
  
  內(nèi)存的分配與回收
  
  請頁機制
  
  交換機制
  
  內(nèi)存共享機制
  
  在具體的讀源碼之前.我們先根據(jù)我們以前學(xué)過的操作系統(tǒng)知識.和C語言等知識.來考慮一下,這幾
  個機制如何實現(xiàn).現(xiàn)自己設(shè)計一下.在看別人是怎樣實現(xiàn)的.找到自己想不到.或者對效率空間有損
  的地方.這樣才有進步.我不止一次的說.操作系統(tǒng)的某一部分,就起實現(xiàn)來說,非常簡單.它的難點
  是如何將大量的功能集成出一個kernerl.
  
  地址映射機制,說白了,就是在虛擬內(nèi)存與物理內(nèi)存上的一個橋梁.它要做的事情可能就是通過幾個
  不同的表.把虛擬地址轉(zhuǎn)換成物理地址,把物理地址轉(zhuǎn)化虛擬地址.
  
  我們以前說過.因為有系統(tǒng)與用戶之分,它必須也要有不同的數(shù)據(jù)結(jié)構(gòu).為了解決速度等問題.它會
  有一個硬件的緩沖區(qū)
  
  對于它的數(shù)據(jù)結(jié)構(gòu).我們可以先想一下.如虛擬地址的信息,虛擬地址在那個區(qū)域等等
  
  至于請頁機制,更好理解.因為linux是頁式存儲的.因此必然會存在空白頁和使用頁.既然是頁.就
  必然會存在頁溢出.頁無效(是不是在win98 下經(jīng)常出現(xiàn)類似錯誤,當(dāng)然linux的內(nèi)存治理不可能和
  windows一樣,可基本道理相同).因此.在每一個頁出錯.或者該頁存不下多余的數(shù)據(jù)時.就要要求內(nèi)
  核分配新的頁面
  
  同時.當(dāng)時用fork() 產(chǎn)生一個新的進程時.也需要分配新的葉面.這一部分大概講的就是進程如何
  向內(nèi)和描述自己需要怎么樣的和多少頁
  
  在我們學(xué)習(xí)<<數(shù)據(jù)結(jié)構(gòu)>>是我們學(xué)了,很多內(nèi)存分配方式,如首次擬和.最佳擬和,最差擬和等等.但
  是我們可以想象.linux 大概不會用他們.那就一定是伙伴系統(tǒng)了.因此我們可以對于伙伴系統(tǒng)的分
  配,回收的基本算法.回想一下.這樣在讀者一部分源碼時,回有意象不到的收獲.
  
  至于交換機制.我們也可以現(xiàn)想一想.內(nèi)存中總與很多使用者的頁.假如這些也已經(jīng)把所有的頁都用
  完了.再分配時必須把其中的某些頁釋放.釋放那些頁,需要考慮.如最近不用頁.近期少用頁,等等
  都可以在考慮之中.
  
  這個算法,大概就是計算內(nèi)存中使用的頁,什么時候可以換處.說白了就是為所有的使用頁計算一
  個”權(quán)”,而這個”權(quán)”就決定了他什么時候被釋放以換如它的內(nèi)容.需要想的是對于經(jīng)常使用的頁.可
  以把它放入cahe.(盡管這一部分對程序員是透明的,但我們應(yīng)該理解他的原理).
  
  最后的一部分共享內(nèi)存,我想和我門初學(xué)linux編程時,進程通訊里面的共享內(nèi)存沒有區(qū)別.大概也
  就是在它的數(shù)據(jù)結(jié)構(gòu)中加入可以答應(yīng)不同進程訪問的tag 就行了.
  
  以上,只是我們對linux的內(nèi)存治理機制的猜測,需要我們做的工作就是具體的讀源碼.更正不正確
  的猜想.同時學(xué)習(xí)別人的實際思路.
  
  
  
  地址的映射機制
  
  地址的映射機制,主要完成主存.輔存.和虛存之間的關(guān)聯(lián).包括磁盤文件到虛存的映射和虛存與內(nèi)
  存的映射關(guān)系.為了虛擬存儲和進程調(diào)度相一致.linux 采用可一系列的數(shù)據(jù)結(jié)構(gòu),和一個硬件緩存
  (TLB)來實現(xiàn)地址映射機制.
  
  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;
  
  };
  
  他描述了一個進程的頁目錄,有關(guān)進程的上下文信息.以及數(shù)據(jù).代碼.堆棧的啟示結(jié)束地址.還有虛
  擬存儲取得數(shù)目.以及調(diào)度存儲用的鏈表指針.他的參差比較高
  
  較高層次的vm_area-struct 是描述進程的虛擬地址區(qū)域.他形成一個算相鏈表.按虛地址下降排列
  .這樣當(dāng)內(nèi)核需要在一個給定進程頁上執(zhí)行給定操作時.客從雙向列表中找到該項.在世想有關(guān)頁的
  處理.如.頁錯誤.頁換出等等
  
  他的具體結(jié)構(gòu)如下:
  
  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 結(jié)構(gòu) 則是對物理頁進行描述的一個數(shù)據(jù)結(jié)構(gòu),他不是一個真正的物理頁.而只不過是描述
  了一個物理頁的內(nèi)容和框架.作了邏輯頁的一個標(biāo)志;.他的標(biāo)志域定義了這個頁在進行的操作.鏈
  域則定義了一個雙項鏈表.時的頁框.可以很輕易的查找到.為實際物理內(nèi)存的使用直到方便
  
  他的具體結(jié)構(gòu)如下
  
  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 結(jié)構(gòu)將都被轉(zhuǎn)入一個叫做mem_map 的數(shù)組中.
  
  當(dāng)一個進程運行時,他的代碼段和數(shù)據(jù)段將都會被調(diào)入內(nèi)存.假如它使用了共享庫.共享客的內(nèi)容也
  將貝雕如內(nèi)存.進程運行時.系統(tǒng)首先分配一

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 九龙城区| 郑州市| 峨眉山市| 上高县| 河北区| 福州市| 钦州市| 滨海县| 吉木萨尔县| 分宜县| 班玛县| 安仁县| 新营市| 东台市| 八宿县| 家居| 杨浦区| 闵行区| 台南市| 黎川县| 砀山县| 海安县| 五台县| 吴旗县| 宝丰县| 原平市| 兰溪市| 林州市| 武隆县| 新巴尔虎右旗| 沁阳市| 客服| 靖宇县| 南康市| 昆山市| 仙游县| 琼海市| 阜阳市| 屯留县| 互助| 南乐县|