linux虛擬地址
A. linux下32位虛擬地址空間是多少
64位的linux採用4級頁表,支持的最大物理內存為64T。 對於虛擬地址空間的劃分,將0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000這128T地址用於用戶空間;而0xffff,8000,0000,0000以上的128T為系統空間地址。 具體的不是一兩句能說清楚了。
B. Linux下怎樣在進程中獲取虛擬地址對應的物理地址
Linux文件目錄中的/proc記錄著當前進程的信息,稱其為虛擬文件系統。在/proc下有一個鏈接目錄名為self,這意味著哪一個進程打開了它,self中存儲的信息就是所鏈接進程的。self中有一個名為page_map的文件,專門用來記錄所鏈接進程的物理頁號信息。這樣通過/proc/pid/page_map文件,允許一個用戶態的進程查看到每個虛擬頁映射到的物理頁
/proc/pid/page_map中的每一項都包含了一個64位的值,這個值內容如下所示。每一項的映射方式不同於真正的虛擬地址映射,其文件中遵循獨立的對應關系,即虛擬地址相對於0x0經過的頁面數是對應項在文件中的偏移量
* /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//present為1時,bit0-54表示物理頁號
* 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)
* Bit 56 page exclusively mapped (since 4.2)
* Bits 57-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present//如果為1,表示當前物理頁在內存中;為0,表示當前物理頁不在內存中
在計算物理地址時,只需要找到虛擬地址的對應項,再通過對應項中的bit63判斷此物理頁是否在內存中,若在內存中則對應項中的物理頁號加上偏移地址,就能得到物理地址
通過程序獲取物理地址並驗證寫時拷貝技術
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
//計算虛擬地址對應的地址,傳入虛擬地址vaddr,通過paddr傳出物理地址
void mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pageSize = getpagesize();//調用此函數獲取系統設定的頁面大小
unsigned long v_pageIndex = vaddr / pageSize;//計算此虛擬地址相對於0x0的經過的頁面數
unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//計算在/proc/pid/page_map文件中的偏移量
unsigned long page_offset = vaddr % pageSize;//計算虛擬地址在頁面中的偏移量
uint64_t item = 0;//存儲對應項的值
int fd = open("/proc/self/pagemap", O_RDONLY);。。以只讀方式打開/proc/pid/page_map
if(fd == -1)//判斷是否打開失敗
{
printf("open /proc/self/pagemap error
");
return;
}
if(lseek(fd, v_offset, SEEK_SET) == -1)//將游標移動到相應位置,即對應項的起始地址且判斷是否移動失敗
{
printf("sleek error
");
return;
}
if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//讀取對應項的值,並存入item中,且判斷讀取數據位數是否正確
{
printf("read item error
");
return;
}
if((((uint64_t)1 << 63) & item) == 0)//判斷present是否為0
{
printf("page present is 0
");
return ;
}
uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//計算物理頁號,即取item的bit0-54
*paddr = (phy_pageIndex * pageSize) + page_offset;//再加上頁內偏移量就得到了物理地址
}
const int a = 100;//全局常量
int main()
{
int b = 100;//局部變數
static c = 100;//局部靜態變數
const int d = 100;//局部常量
char *str = "Hello World!";
unsigned long phy = 0;//物理地址
char *p = (char*)malloc(100);//動態內存
int pid = fork();//創建子進程
if(pid == 0)
{
//p[0] = '1';//子進程中修改動態內存
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
else
{
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
sleep(100);
free(p);
waitpid();
return 0;
}
測試結果如下:
全局常量:符合寫時拷貝技術
子進程修改動態內存
*其實想要知道虛擬地址對應的物理地址,通過這樣的方式也可以得到物理地址而不用操作MMU。。。*
以上就是Linux下怎樣在進程中獲取虛擬地址對應的物理地址的全文介紹,希望對您學習和使用linux系統開發有所幫助.
C. linux虛地址空間理論上的大小
在多任務操作系統中,每個進程都運行在屬於自己的內存沙盤中。這個沙盤就是虛擬地址空間(Virtual Address Space),在32位模式下它是一個4GB的內存地址塊。在Linux系統中, 內核進程和用戶進程所佔的虛擬內存比例是1:3,而Windows系統為2:2(通過設置Large-Address-Aware Executables標志也可為1:3)。這並不意味著內核使用那麼多物理內存,僅表示它可支配這部分地址空間,根據需要將其映射到物理內存。
虛擬地址通過頁表(Page Table)映射到物理內存,頁表由操作系統維護並被處理器引用。內核空間在頁表中擁有較高特權級,因此用戶態程序試圖訪問這些頁時會導致一個頁錯誤(page fault)。在Linux中,內核空間是持續存在的,並且在所有進程中都映射到同樣的物理內存。內核代碼和數據總是可定址,隨時准備處理中斷和系統調用。與此相反,用戶模式地址空間的映射隨進程切換的發生而不斷變化。
D. linux系統怎麼設置虛擬機的ip地址
1.有界面的方式 1.點擊虛擬機–>設置–>將網路適配器改為橋接模式 2.回到主頁面,點擊右上角的兩個小電腦,斷開鏈接,然後選擇VPN Connections–>config vpn 選擇system eth0 ...
2.沒有界面,遠程連接的方式 找到/etc/sysconfig/network-scripts目錄,裡面有一個ifcfg-etho...
3.用ssh方式連入虛擬機 SSH是一種網路協議,用於計算機之間的加密登錄,ssh命令
E. linux中虛擬地址和物理地址怎樣映射
虛擬就是虛擬的,不是實際真是的物理地址。你可以認為,這兩個地址之間沒關系。
這個虛擬是通過系統和硬體的雙重工作,做的一種點對點的映射(當然實際內存分配是按照頁來處理)。
也就是軟體不需要考慮內存數據的物理地址,只需要用虛擬地址做數據存儲處理就行了。
這樣一個好處是,軟體不需要自己做內存分配,也不需要考慮別的軟體的內存佔用問題。操作系統會根據當前的內存使用情況,動態的分配內存空間。虛擬內存地址還一個好處是因為是虛擬的,所以內存並不一定非要在物理內存中。可以存放在任何位置,比如把暫時不用的數據放進硬碟上的虛擬內存,騰出真實的物理內存交給程序運行而提高多程序時運行的效率。而且因為每個軟體的虛擬內存地址都是從 0 開始,每個軟體的定址都是獨立而且順序的。程序編寫和運行時,都好像是機器裡面只有自己一個程序在運行,程序開發起來也很容易。軟體不需要考慮內存分配的問題,也不需要擔心內存不足和兩個程序搶同一片內存導致系統整個崩潰的情況。
F. 如何在linux虛擬機修改ip地址
您好,方法
1、依次打開之前拷貝的三個虛擬機,查看當前的IP;
2、進入虛擬機配置IP的配置文件目錄;
cd /etc/sysconfig/network-scripts/
3、進入目錄後,查看當前目錄下的文件,輸入命令ls;
4、切換root許可權,並輸入密碼;
5、開始修改配置文件,輸入命令:vim ifcfg-eth0,進入配置文件;
6、修改IP為11節點、DNS信息;
7、保存配置文件信息;
8、重啟網路服務,輸入命令: /etc/init.d/network restart;
9、服務重啟成功;
10、查看當前虛擬機的IP地址,輸入命令:ifconfig;
由於Slave1虛擬機是從Master中復制來的,則其對應的物理網卡是一樣的;
接下來將修改Slave1的網卡信息;
11、點擊Slave1虛擬機右下角的小電腦,即網路適配器,點擊網路適配器--移除,進行移除網路配置;
12、點擊添加--下一步--下一步,完成,開始添加網路適配器;
13、查看物理網路地址:ifconfig,可以看出現在的物理網卡地址與Master節點不同;
14、用同等方法進行配置Slave2。
G. linux 為什麼採用虛擬地址
不光Linux用的是是虛擬內存地址,Windows也是用虛擬內存地址,CPU的保護模式下訪問內存都是用的虛擬內存地址,這是CPU保護模式下的內存管理方式決定的,只有在實模式下才會直接訪問物理內存。
H. linux 怎樣查看綁定的虛擬ip
你說的虛擬IP地址是不是指虛擬機,虛擬機的設置 《Linux就該這么學》第一章節中圖1-21 你選擇的模式是哪一種,就是那種IP地址
橋接模式 NAT模式 僅主機模式
打開Linux終端
2.輸入命令,並且執行ifconfig
3.查看結果,其中inet addr 就是本機ip地址
I. linux 虛擬地址,到底怎麼理解
不是僅僅 Linux 是這么設計的,整個現代流行的操作系統都是這么設計的。
應用程序被讀入內存後,為了保證系統的統一性,所有的程序都有同樣的一套定址規范。這個定址就是虛擬地址。這個虛擬地址是系統提供轉換的,不是程序的工作。
如果系統不提供這個功能,那麼應用程序就需要自己去尋找沒有被使用的內存,以及還要自己去處理內存容量的問題,而且如果程序調用外部的一些函數庫,這些函數庫也需要分配內存,這會導致應用程序的設計難度非常大,每個應用程序實際上就是一個操作系統了。多個程序共同運行導致內存使用混亂也很容易出現。
應用程序申請內存,使用的是操作系統的內存分配功能。這樣操作系統可以根據實際情況給應用程序內存,程序不需要考慮因為內存位置不同而必須不同編寫的難度。而且操作系統還可以提供虛擬內存等等各種方式來擴充內存,這樣的內存對於應用程序來說是不需要考慮的,一切都有系統打理。
使用虛擬地址後,對於應用程序來說,他的內存使用不需要考慮其他的程序佔用,也不需要考慮內存容量的問題,也不需要考慮內存塊位置,函數庫的調用也都扔給操作系統打理。這使得應用程序不需要考慮具體如何管理內存,只需要考慮作為應用程序的應用部分。
而且,因為內存是虛擬的,應用程序一些函數調用,操作系統可以把多個應用程序的調用都用同一套數據來處理,這樣,既可以節約內存使用(就是啟動100個應用程序,也只需要內存里有一套函數庫而已),也可以做到外部函數庫和應用程序沒有直接關聯,純粹是由系統做虛擬地址過渡。
至於為什麼 4G ,這是傳統+一些兼容的考慮。
以前沒有這個技術時,每個程序都可以完全使用整個系統,整個空間是連續的。到了這種虛擬地址的方式後,每個程序還是有自己「獨立」的一整套內存地址。但每個程序內存使用量肯定不一樣。那麼多少內存空間才完全夠用呢?當時因為正好使用了 32 位系統。那麼就把整個 32 位環境支持的 4G 內存容量作為這個極限。
不過因為內存地址是虛擬的。實際應用程序要用內存,是需要先申請的,所以只有程序申請後,真實內存才會被佔用。這個 4G 只是在演算法上作為極限。
不過因為 4G 也是硬體極限。所以 4G 以外的地址都是不能使用的,這就導致另一個問題,一些硬體有存儲器,有些硬體需要存儲空間做交互(比如 PCI ,比如各種硬體,比如 AGP 顯卡)。這些存儲區域怎麼處理?
所以,Windows Vista 的 32 位版在 4G 內存的機器上曾經報出只有 3.5G (有的機器甚至只有 3.25G 可以用)。就是這個問題的解決辦法導致的:把硬體的內存用虛擬地址的方式,放到虛擬地址的最後面。這樣應用程序調用硬體存儲時,可以直接按照內存的方式讀寫。這樣應用程序就很好的統一了存儲界面:只有 4G 的內存范圍,不存在其他方式的存儲調用方式(硬碟需要用讀寫功能讀取到內存後才能處理,而不是直接進行處理)。這樣應用程序的開發就很簡單,而且整個內存的使用每個程序都一樣。不存在各種硬體的原因而不同導致的需要重新設計內存管理演算法。操作系統也能根據實際應用程序的需要隨時分配數據,也可以根據每個程序的運行情況,區別的提供物理內存或者虛擬的內存。
這么設計最大的一個好處是,硬體環境和應用程序是無關的,中間由操作系統做轉換。而且應用程序互相之間也沒有影響,就好象整個內存都由他自己一個程序使用一樣。
PS:說了半天,我發現我自己也說不清楚其中的緣由……
J. Linux 虛擬地址空間如何分布
一個進程的虛擬地址空間主要由兩個數據結來描述。一個是最高層次的:mm_struct,一個是較高層次的:vm_area_structs。最高層次的mm_struct結構描述了一個進程的整個虛擬地址空間。較高層次的結構vm_area_truct描述了虛擬地址空間的一個區間(簡稱虛擬區)。
1. MM_STRUCT結構
mm_strcut 用來描述一個進程的虛擬地址空間,在/include/linux/sched.h 中描述如下:
struct mm_struct {
struct vm_area_struct * mmap; /* 指向虛擬區間(VMA)鏈表 */
rb_root_t mm_rb; /*指向red_black樹*/
struct vm_area_struct * mmap_cache; /* 指向最近找到的虛擬區間*/
pgd_t * pgd; /*指向進程的頁目錄*/
atomic_t mm_users; /* 用戶空間中的有多少用戶*/
atomic_t mm_count; /* 對"struct mm_struct"有多少引用*/
int map_count; /* 虛擬區間的個數*/
struct rw_semaphore mmap_sem;
spinlock_t page_table_lock; /* 保護任務頁表和 mm->rss */
struct list_head mmlist; /*所有活動(active)mm的鏈表 */
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_address;
unsigned mpable:1;
/* Architecture-specific MM context */
mm_context_t context;
};
對該結構進一步說明如下:
在內核代碼中,指向這個數據結構的變數常常是mm。
每個進程只有一個mm_struct結構,在每個進程的task_struct結構中,有一個指向該進程的結構。可以說,mm_struct結構是對整個用戶空間的描述。
一個進程的虛擬空間中可能有多個虛擬區間(參見下面對vm_area_struct描述),對這些虛擬區間的組織方式有兩種,當虛擬區較少時採用單鏈表,由mmap指針指向這個鏈表,當虛擬區間多時採用「紅黑樹(red_black
tree)」結構,由mm_rb指向這顆樹。在2.4.10以前的版本中,採用的是AVL樹,因為與AVL樹相比,對紅黑樹進行操作的效率更高。
因為程序中用到的地址常常具有局部性,因此,最近一次用到的虛擬區間很可能下一次還要用到,因此,把最近用到的虛擬區間結構應當放入高速緩存,這個虛擬區間就由mmap_cache指向。
指針pgt指向該進程的頁目錄(每個進程都有自己的頁目錄,注意同內核頁目錄的區別),當調度程序調度一個程序運行時,就將這個地址轉成物理地址,並寫入控制寄存器(CR3)。
由於進程的虛擬空間及其下屬的虛擬區間有可能在不同的上下文中受到訪問,而這些訪問又必須互斥,所以在該結構中設置了用於P、V操作的信號量mmap_sem。此外,page_table_lock也是為類似的目的而設置。
雖然每個進程只有一個虛擬地址空間,但這個地址空間可以被別的進程來共享,如,子進程共享父進程的地址空間(也即共享mm_struct結構)。所以,用mm_user和mm_count進行計數。類型atomic_t實際上就是整數,但對這種整數的操作必須是「原子」的。
另外,還描述了代碼段、數據段、堆棧段、參數段以及環境段的起始地址和結束地址。這里的段是對程序的邏輯劃分,與我們前面所描述的段機制是不同的。
mm_context_t是與平台相關的一個結構,對i386 幾乎用處不大。
在後面對代碼的分析中對有些域給予進一步說明。
2. VM_AREA_STRUCT 結構
vm_area_struct描述進程的一個虛擬地址區間,在/include/linux/mm.h中描述如下:
struct vm_area_struct
struct mm_struct * vm_mm; /* 虛擬區間所在的地址空間*/
unsigned long vm_start; /* 在vm_mm中的起始地址*/
unsigned long vm_end; /*在vm_mm中的結束地址 */
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next;
pgprot_t vm_page_prot; /* 對這個虛擬區間的存取許可權 */
unsigned long vm_flags; /* 虛擬區間的標志. */
rb_node_t vm_rb;
/*
* For areas with an address space and backing store,
* one of the address_space->i_mmap{,shared} lists,
* 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;
/* Information about our backing store: */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units, *not* PAGE_CACHE_SIZE */
struct file * vm_file; /* File we map to (can be NULL). */
unsigned long vm_raend; /* XXX: put full readahead info here. */
void * vm_private_data; /* was vm_pte (shared mem) */
};
vm_flag是描述對虛擬區間的操作的標志,其定義和描述如下
標志名 描述
VM_DENYWRITE 在這個區間映射一個打開後不能用來寫的文件。
VM_EXEC 頁可以被執行。
VM_EXECUTABLE 頁含有可執行代碼。
VM_GROWSDOWN 這個區間可以向低地址擴展。
VM_GROWSUP 這個區間可以向高地址擴展。
VM_IO 這個區間映射一個設備的I/O地址空間。
VM_LOCKED 頁被鎖住不能被交換出去。
VM_MAYEXEC VM_EXEC 標志可以被設置。
VM_MAYREAD VM_READ 標志可以被設置。
VM_MAYSHARE VM_SHARE 標志可以被設置。
VM_MAYWRITE VM_WRITE 標志可以被設置。
VM_READ 頁是可讀的。
VM_SHARED 頁可以被多個進程共享。
VM_SHM 頁用於IPC共享內存。
VM_WRITE 頁是可寫的。
較高層次的結構vm_area_structs是由雙向鏈表連接起來的,它們是按虛地址的降順序來排列的,每個這樣的結構都對應描述一個相鄰的地址空間范圍。之所以這樣分割,是因為每個虛擬區間可能來源不同,有的可能來自可執行映象,有的可能來自共享庫,而有的則可能是動態分配的內存區,所以對每一個由vm_area_structs結構所描述的區間的處理操作和它前後范圍的處理操作不同。因此Linux
把虛擬內存分割管理,並利用了虛擬內存處理常式(vm_ops)來抽象對不同來源虛擬內存的處理方法。不同的虛擬區間其處理操作可能不同,Linux在這里利用了面向對象的思想,即把一個虛擬區間看成一個對象,用vm_area_structs描述了這個對象的屬性,其中的vm_operation結構描述了在這個對象上的操作,其定義在/include/linux/mm.h中:
/*
* These are the virtual MM functions - opening of an area, closing and
* unmapping it (needed to keep files on disk up-to-date etc), pointer
* to the functions called when a no-page or a wp-page exception occurs.
*/
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 unused);
};
vm_operations結構中包含的是函數指針;其中,open、close分別用於虛擬區間的打開、關閉,而nopage用於當虛存頁面不在物理內存而引起的「缺頁異常」時所應該調用的函數。
3.紅黑樹結構
Linux內核從2.4.10開始,對虛擬區的組織不再採用AVL樹,而是採用紅黑樹,這也是出於效率的考慮,雖然AVL樹和紅黑樹很類似,但在插入和刪除節點方面,採用紅黑樹的性能更好一些,下面對紅黑樹給予簡單介紹。
一顆紅黑樹是具有以下特點的二叉樹:
每個節點著有顏色,或者為紅,或者為黑
根節點為黑色
如果一個節點為紅色,那麼它的子節點必須為黑色
從一個節點到葉子節點上的所有路徑都包含有相同的黑色節點數