国产宅男网站在线|亚洲A级性爱免费视频|亚洲中精品级在线|午夜福利AA毛

  • <dd id="gf5jf"><th id="gf5jf"></th></dd>

    <cite id="gf5jf"><label id="gf5jf"></label></cite>
  • <div id="gf5jf"><listing id="gf5jf"></listing></div>
    學(xué)習(xí)啦>學(xué)習(xí)電腦>電腦知識大全>

    linux虛擬地址怎么映射物理地址

    時間: 曉斌668 分享

      linux虛擬地址怎么映射物理地址這個問題大家都想知道吧?下面學(xué)習(xí)啦小編就給大家介紹下linux虛擬地址怎么映射物理地址的。

      linux虛擬地址怎么映射物理地址

      1. 虛擬空間(首先學(xué)習(xí)啦小編必須要給大家介紹下什么是Linux操作系統(tǒng)的虛擬空間)

      0-3G 用戶空間 0x00000000 ~ 0xbfffffff

      3-4G 內(nèi)核空間 0xc0000000 ~ 0xffffffff

      每個用戶進(jìn)程都有獨立的用戶空間(虛擬地址0-3),而內(nèi)核空間是唯一的(相當(dāng)于共享)

      每個進(jìn)程的用戶空間用mm_struct描述,即task_struct.mm。

      2.進(jìn)程虛擬地址的組織

      2.1 虛擬空間、用戶空間

      [cpp] view plaincopy

      struct mm_struct {

      struct vm_area_struct * mmap; /* list of VMAs */

      ...

      pgd_t * pgd; //用于地址映射

      atomic_t mm_users; /* How many users with user space? */

      atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */

      int map_count; /* number of VMAs */

      ...

      //描述用戶空間的段分布:數(shù)據(jù)段,代碼段,堆棧段

      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;

      ...

      };

      以上結(jié)構(gòu)描述了進(jìn)程的用戶空間的結(jié)構(gòu),其中

      pgd_t 是該進(jìn)程用戶空間地址映射到物理地址時使用

      vm_area_struct 是進(jìn)程用戶空間已映射到物理空間的虛擬地址區(qū)間,mmap是該空間區(qū)塊組成的鏈表。

      虛擬空間的空洞:虛擬空間還未被映射的區(qū)塊(即沒有被使用),那么就沒有vm_area_struct結(jié)構(gòu)

      2.2 內(nèi)存區(qū)間

      [cpp] view plaincopy

      /*

      * This struct defines a memory VMM memory area. There is one of these

      * per VM-area/task. A VM area is any part of the process virtual memory

      * space that has a special rule for the page-fault handlers (ie a shared

      * library, the executable area etc).

      */

      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;

      //該區(qū)間的權(quán)限及標(biāo)志

      pgprot_t vm_page_prot;

      unsigned long vm_flags;

      //一些vm_area 的鏈接

      ...

      struct vm_operations_struct * vm_ops;

      unsigned long vm_pgoff; /* offset in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */

      struct file * vm_file; //用于將磁盤文件映射至用戶空間

      ...

      };

      虛擬空間區(qū)間的描述中:

      vm_start/vm_end 為該區(qū)塊的起始和結(jié)束地址

      vm_file 是在文件映射中使用到,即常用的mmap(fd,...)函數(shù),簡單說即將虛擬空間映射至文件在內(nèi)核的緩沖區(qū),那么這時候訪問該虛擬空間將有別于pgd的映射。

      vm_operations_struct 為本虛擬區(qū)間的操作,其中的nopage函數(shù)指針是處理內(nèi)存缺頁而使用的。對于通用的內(nèi)存映射,該缺頁處理函數(shù)為do_no_page()將虛擬地址映射到物理地址(匿名映射):分配物理頁& 設(shè)置pgd & pte。

      而對于mmap操作相關(guān)的虛擬地址,其缺頁處理函數(shù)將和文件系統(tǒng)的缺頁函數(shù)相關(guān),filemap_nopage(),通過文件系統(tǒng)的缺頁從磁盤將相關(guān)文件塊加載如內(nèi)核緩沖區(qū).

      [cpp] view plaincopy

      struct vm_operations_struct {

      void (*open)(struct vm_area_struct * area);

      void (*close)(struct vm_area_struct * area);

      struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access); //缺頁操作

      };

      3.系統(tǒng)物理地址的組織

      內(nèi)核將物理地址按頁來組織,struct page描述系統(tǒng)的物理頁的信息,但是頁的數(shù)據(jù)內(nèi)容是不在該結(jié)構(gòu)中的。系統(tǒng)有全局?jǐn)?shù)據(jù) struct page mem_map[],用于記錄每個物理頁。

      頁面大小為4kb,在源碼中用體現(xiàn)為(PAGE_SHIFT = 12)

      [cpp] view plaincopy

      /*

      * Try to keep the most commonly accessed fields in single cache lines

      * here (16 bytes or greater). This ordering should be particularly

      * beneficial on 32-bit processors.

      *

      * The first line is data used in page cache lookup, the second line

      * is used for linear searches (eg. clock algorithm scans).

      */

      typedef struct page {

      struct list_head list;

      struct address_space *mapping;

      unsigned long index;

      struct page *next_hash;

      atomic_t count;

      unsigned long flags; /* atomic flags, some possibly updated asynchronously */

      struct list_head lru;

      unsigned long age;

      wait_queue_head_t wait;

      struct page **pprev_hash;

      struct buffer_head * buffers;

      void *virtual; /* non-NULL if kmapped */

      struct zone_struct *zone;

      } mem_map_t;

      struct page是用于描述一個物理頁面,該結(jié)構(gòu)僅僅是作為描述,也就是說該頁面的4kb數(shù)據(jù)時存儲于某個連續(xù)的4kb的物理空間(由MMU決定,具體見下文)。其中:

      lru 頁面緩沖的調(diào)度策略(最少使用優(yōu)先)

      題外話:

      page也可以用于文件緩沖,相關(guān)參數(shù)及作用:

      buffer_head 是和設(shè)備文件相關(guān)的操作,例如在文件系統(tǒng)中,file的一個page有4個塊,這些塊就存儲于buffer_head鏈表指定的內(nèi)存中。

      index 在文件系統(tǒng)中是用于file緩沖的頁號。

      3.1 用戶空間頁面目錄(映射關(guān)系)

      進(jìn)程的虛擬空間描述中,pgd是用于頁式存儲的映射使用。當(dāng)內(nèi)核發(fā)生進(jìn)程切換時,將新進(jìn)程的pgd載入CR3寄存器,CPU中的MMU單元依據(jù)CR3寄存器進(jìn)行頁面映射。

      pgd,pmd和pte可以看做是數(shù)組,為進(jìn)程的地址空間到物理空間實現(xiàn)映射。其中虛擬地址的高位地址決定pgd,中間段地址決定pmd,而低位地址決定pte,pte是“page table entry”。

      最終定位的pte中存放的即為對應(yīng)物理頁面的指針。[cpp] view plaincopy

      typedef struct { unsigned long pte; } pte_t;

      typedef struct { unsigned long pmd; } pmd_t;

      typedef struct { unsigned long pgd; } pgd_t;

      typedef struct { unsigned long pgprot; } pgprot_t; //操作標(biāo)志

      3.2用戶空間的映射:

      1. 用戶空間的虛擬地址vaddr通過MMU(pgd,pmd,pte)找到對應(yīng)的頁表項x(即為物理地址)

      2. 頁表項x的高20位是物理也好,物理頁號index = x >> PAGE_SHIFT, 同理,index后面補(bǔ)上12個0就是物理頁表的首地址。

      3. 通過物理頁號,我們可以再內(nèi)核中找到該物理頁的描述的指針mem_map[index],當(dāng)然這個指針是虛擬地址,page結(jié)構(gòu)見上文。

      3.3內(nèi)核空間虛擬地址的映射:

      內(nèi)核空間與物理地址之間有直接的映射關(guān)系,而不需要向用戶空間那樣通過mmu(pgd)。系統(tǒng)空間映射(3G開始)到物理空間0G起始:

      例如:

      系統(tǒng)內(nèi)核映像載入的虛擬地址為3G+1M的起始地址,那么對應(yīng)的物理地址為1M。

      緊接著分配在3G+2M開始分配了8M的虛擬地址(物理地址為2-9M)用于PDG

      之后預(yù)留了16M空間用DMA于存儲。

      而全局的page結(jié)構(gòu)的mem_page[]數(shù)組是在0xc1000000開始的。

      所以內(nèi)核空間虛擬地址到物理地址的轉(zhuǎn)換為:

      [cpp] view plaincopy

      PAGE_OFFSET = 3GB

      vitr_to_phys(kadd)

      return vadd - PAGE_OFFSET

      內(nèi)核空間的虛擬地址vaddr是通過如下方式找到它對應(yīng)物理地址的page結(jié)構(gòu):

      vitr_to_page(vadd)

      index = virt_to_phys(kadd) >> PAGE_SHIFT

      return mem_map[index]

      4. 相關(guān)數(shù)據(jù)結(jié)構(gòu)關(guān)系圖

      說明:

      1. 黑色+紅色 箭頭展示了虛擬地址空間到物理空間的映射關(guān)系

      2. 藍(lán)色箭頭涉涉及到文件的映射操作mmap(),相比匿名映射,文件映射多了文件層的磁盤IO。

    409123