• <output id="aynwq"><form id="aynwq"><code id="aynwq"></code></form></output>

    <mark id="aynwq"><option id="aynwq"></option></mark>
  • <mark id="aynwq"><option id="aynwq"></option></mark><label id="aynwq"><dl id="aynwq"></dl></label>
  • 學習啦 > 學習電腦 > 網絡知識 > 網絡基礎知識 > 虛擬地址物理地址

    虛擬地址物理地址

    時間: 春健736 分享

    虛擬地址物理地址

      ?學習啦小編整理了虛擬地址物理地址的相關資料。供大家參考!

      虛擬地址和物理地址的概念

      CPU通過地址來訪問內存中的單元,地址有虛擬地址和物理地址之分,如果CPU沒有MMU(Memory Management Unit,內存管理單元),或者有MMU但沒有啟用,CPU核在取指令或訪問內存時發出的地址將直接傳到CPU芯片的外部地址引腳上,直接被內存芯片(以下稱為物理內存,以便與虛擬內存區分)接收,這稱為物理地址(Physical Address,以下簡稱PA),如下圖所示。

      物理地址示意圖

      如果CPU啟用了MMU,CPU核發出的地址將被MMU截獲,從CPU到MMU的地址稱為虛擬地址(Virtual Address,以下簡稱VA),而MMU將這個地址翻譯成另一個地址發到CPU芯片的外部地址引腳上,也就是將虛擬地址映射成物理地址,如下圖所示[1]。

      虛擬地址示意圖

      MMU將虛擬地址映射到物理地址是以頁(Page)為單位的,對于32位CPU通常一頁為4K。例如,虛擬地址0xb700 1000~0xb700 1fff是一個頁,可能被MMU映射到物理地址0x2000~0x2fff,物理內存中的一個物理頁面也稱為一個頁框(Page Frame)。

      內核也不能直接訪問物理地址.但因為內核的虛擬地址和物理地址之間只是一個差值0xc0000000的區別,所以從物理地址求虛擬地址或從虛擬地址求物理地址很容易,+-這個差就行了

      物理地址(physical address)

      用于內存芯片級的單元尋址,與處理器和CPU連接的地址總線相對應。

      ——這個概念應該是這幾個概念中最好理解的一個,但是值得一提的是,雖然可以直接把物理地址理解成插在機器上那根內存本身,把內存看成一個從0字節一直到最大空量逐字節的編號的大數組,然后把這個數組叫做物理地址,但是事實上,這只是一個硬件提供給軟件的抽像,內存的尋址方式并不是這樣。所以,說它是“與地址總線相對應”,是更貼切一些,不過拋開對物理內存尋址方式的考慮,直接把物理地址與物理的內存一一對應,也是可以接受的。也許錯誤的理解更利于形而上的抽像。

      虛擬內存(virtual memory)

      這是對整個內存(不要與機器上插那條對上號)的抽像描述。它是相對于物理內存來講的,可以直接理解成“不直實的”,“假的”內存,例如,一個0x08000000內存地址,它并不對就物理地址上那個大數組中0x08000000 - 1那個地址元素;

      之所以是這樣,是因為現代操作系統都提供了一種內存管理的抽像,即虛擬內存(virtual memory)。進程使用虛擬內存中的地址,由操作系統協助相關硬件,把它“轉換”成真正的物理地址。這個“轉換”,是所有問題討論的關鍵。

      有了這樣的抽像,一個程序,就可以使用比真實物理地址大得多的地址空間。(拆東墻,補西墻,銀行也是這樣子做的),甚至多個進程可以使用相同的地址。不奇怪,因為轉換后的物理地址并非相同的。

      ——可以把連接后的程序反編譯看一下,發現連接器已經為程序分配了一個地址,例如,要調用某個函數A,代碼不是call A,而是call 0x0811111111 ,也就是說,函數A的地址已經被定下來了。沒有這樣的“轉換”,沒有虛擬地址的概念,這樣做是根本行不通的。

      Linux下獲取虛擬地址對應的物理地址的方法

      * /proc/pid/pagemap. This file lets a userspace process find out which

      physical frame each virtual page is mapped to. It contains one 64-bit

      value for each virtual page, containing the following data (from

      fs/proc/task_mmu.c, above pagemap_read):

      * Bits 0-54 page frame number (PFN) if present

      * Bits 0-4 swap type if swapped

      * Bits 5-54 swap offset if swapped

      * Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)

      * Bits 56-60 zero

      * Bit 61 page is file-page or shared-anon

      * Bit 62 page swapped

      * Bit 63 page present

      If the page is not present but in swap, then the PFN contains an

      encoding of the swap file number and the page's offset into the

      swap. Unmapped pages return a null PFN. This allows determining

      precisely which pages are mapped (or in swap) and comparing mapped

      pages between processes.

      接下來,我們根據上述描述,給出獲取虛擬地址對應的物理地址的代碼

      #include <stdio.h>

      #include <stdint.h>

      #include <sys/types.h>

      #include <sys/stat.h>

      #include <fcntl.h>

      #include <unistd.h>

      #define page_map_file "/proc/self/pagemap"

      #define PFN_MASK ((((uint64_t)1)<<55)-1)

      #define PFN_PRESENT_FLAG (((uint64_t)1)<<63)

      int mem_addr_vir2phy(unsigned long vir, unsigned long *phy)

      {

      int fd;

      int page_size=getpagesize();

      unsigned long vir_page_idx = vir/page_size;

      unsigned long pfn_item_offset = vir_page_idx*sizeof(uint64_t);

      uint64_t pfn_item;

      fd = open(page_map_file, O_RDONLY);

      if (fd<0)

      {

      printf("open %s failed", page_map_file);

      return -1;

      }

      if ((off_t)-1 == lseek(fd, pfn_item_offset, SEEK_SET))

      {

      printf("lseek %s failed", page_map_file);

      return -1;

      }

      if (sizeof(uint64_t) != read(fd, &pfn_item, sizeof(uint64_t)))

      {

      printf("read %s failed", page_map_file);

      return -1;

      }

      if (0==(pfn_item & PFN_PRESENT_FLAG))

      {

      printf("page is not present");

      return -1;

      }

      *phy = (pfn_item & PFN_MASK)*page_size + vir % page_size;

      return 0;

      }

      如果擔心vir地址對應的頁面不在內存中,可以在調用mem_addr_vir2phy之前,先訪問一下此地址。

      例如, int a=*(int *)(void *)vir;

      如果擔心Linux的swap功能將進程的頁面交換到硬盤上從而導致頁面的物理地址變化,可以關閉swap功能。

      下面兩個C庫函數可以阻止Linux將當前進程的部分或全部頁面交換到硬盤上。

      int mlock(const void *addr, size_t len);

      int mlockall(int flags);

      看過“虛擬地址空間映射到物理地址空間 ”的人還看了:

    1.物理地址和虛擬地址

    2.虛擬地址到物理地址的轉換

    3.物理地址與虛擬地址怎么轉換

    4.物理地址與虛擬地址映射

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

    604412 主站蜘蛛池模板: 国产鲁鲁视频在线观看| 亚洲风情亚aⅴ在线发布| 看免费的黄色片| 亚洲色图13p| 欧美成人aaa大片| 久久青草国产免费观看| 日本一本一区二区| 一级毛片免费播放男男| 天天操天天干天天干| 69精品久久久久| 国产成年无码久久久免费| 阿娇被躁120分钟视频| 午夜福利视频合集1000| 熟妇人妻中文字幕无码老熟妇| 亚洲成a人片在线观看www| 最新更新国内自拍视频| 丰满多毛的大隂户毛茸茸| 小仙女坐在胯下受辱h| 97国产在线视频公开免费| 国产欧美视频在线观看| 色欲香天天天综合网站| 免费国产a国产片高清网站| 欧美牲交a欧美牲交aⅴ免费下载| 五月婷婷色综合| 打开腿给医生检查黄文| j8又粗又大又长又爽又硬男男| 国产高清在线精品免费软件| 国产乱子精品免费视观看片| 国产1区2区在线观看| 激情综合色五月六月婷婷| 亚洲av最新在线观看网址| 无码人妻一区二区三区av| caopon国产在线视频| 国产精品va一级二级三级| 色妞妞www精品视频| 人善交video欧美| 最近最新中文字幕| 中文在线免费观看| 国产色综合久久无码有码| 香港三日本8A三级少妇三级99| 公的大龟慢慢挺进我的体内视频|