1. linux進程中頁表一般在內存的什麼地址段
重新設置任務結構中的TSS結構的各個欄位值。讓新進程的狀態保持父進程即將進入中斷過程前的狀態,然後為新進程確定在線性地址空間的起始位置(nr * 64MB)。對於CPU分段機制,linux0.11的代碼段和數據段在線性地址空間中的位置和長度完全相同。...
2. linux如何看物理地址
1、這里以ubuntu為例,抄演示查看物理網卡地址的方法,首先按下Alt+F12打開終端輸入框:
2、然後輸入命令「ifconfig -a」,這里該命令類似於windows下的ipconfig命令:
3、按下回車後就會出現網卡的詳細信息了,這里的高亮部分即是ip信息,網卡物理地址在最後第二行顯示:
3. 不太明白LINUX的邏輯地址,線性地址,物理地址之間的關系各是用來解決什麼問題的呢
linux裡面通過邏輯地址來得到線性地址,再有線性地址得到物理地址。
其中物理地址是實際的地址。
邏輯地址和線性地址是linux方便自己系統管理內存而使用的機制。
4. linux 下通過某個ip查找mac 地址 命令
1.首先,右鍵點擊桌面,選擇「打開終端」,或者按CTRL+Alt+T打開終端。
5. linux下的分段分頁機制將一個邏輯地址轉換到物理地址的問題
你要問的應該是Intel系列CPU的定址吧?其他系列的CPU沒有邏輯地址線性地址以及程序地址之分的,這三者是同一回事,但是Intel系列CPU為了保持向前兼容,不得已這樣做的。以80386為例簡單說一下吧:
在以前Intel8086中邏輯地址是這樣的格式,16位段地址(CS,DS,SS,ES):16位段內偏移。
在80386中,為了兼容8086,新增兩個段寄存器,一個是全局性的段描述表寄存器GDTR,另一個是局部性的段描述表寄存器LDTR,分別用來指向存儲在內存中的一個段描述結構數組,或稱為段描述表。
在此基礎上,段寄存器的高13位用作訪問段描述表中具體描述結構的下標(index),如下圖:
結構中的B31~B24和B23~B16分別為基地址的bit16~bit23和bit24~bit31。這樣,16位基地值確定了,將這16位地址左移16位,與上邏輯地址的16位段內偏移地址,就得到32位的線性地址,其後的線性地址到物理地址的轉換你明白的,就不多說了。
6. 如何在LINUX中獲取進程中某個虛擬地址所在物理內
/*
*偽代碼,示例
*32位地址,三級映射(沒有pud_t),頁面大小4KB
*/
unsigned long addr = 0x12345678;//要找的虛擬地址,用戶空間所訪問的地址
unsigned long real_addr = 0x00;//要輸出的地址
struct task_struct *cur_task = get_current();//獲取當前進程式控制制塊
struct mm_struct *mm = cur_task -> mm;//進程虛擬空間
pgd_t *pgd;//描述頁全局目錄項
pmd_t *pmd;//描述頁中間項
pte_t *pte;//頁表項
pgd = pgd_offset(mm, addr);//找出所在目錄
if (pgd_none(*pgd)){
goto out;
}
pmd = pmd_offset(pgd, addr);//找出所在中間項
if (pmd_none(*pmd)){
goto out;
}
pte = pte_offset(pmd, addr);//找出所在頁面
if (pte_none(*pte)) {
goto out;
}
//假設每頁4KB
real_addr = addr & 0x00003fff; //取出頁面偏移量
real_addr += pte;//內核空間訪問的地址
real_addr -= PAGE_OFFSET;//真正物理地址()
printk("物理地址是 %x\n",real_addr);
return;
out:
printk("沒有內存映射",real_addr);
7. linux中虛擬地址和物理地址怎樣映射
/*
*偽代碼,示例
*32位地址,三級映射(沒有pud_t),頁面大小4KB
*/
unsigned long addr = 0x12345678;//要找的虛擬地址,用戶空間所訪問的地址
unsigned long real_addr = 0x00;//要輸出的地址
struct task_struct *cur_task = get_current();//獲取當前進程式控制制塊
struct mm_struct *mm = cur_task -> mm;//進程虛擬空間
pgd_t *pgd;//描述頁全局目錄項
pmd_t *pmd;//描述頁中間項
pte_t *pte;//頁表項
pgd = pgd_offset(mm, addr);//找出所在目錄
if (pgd_none(*pgd)){
goto out;
}
pmd = pmd_offset(pgd, addr);//找出所在中間項
if (pmd_none(*pmd)){
goto out;
}
pte = pte_offset(pmd, addr);//找出所在頁面
if (pte_none(*pte)) {
goto out;
}
//假設每頁4KB
real_addr = addr & 0x00003fff; //取出頁面偏移量
real_addr += pte;//內核空間訪問的地址
real_addr -= PAGE_OFFSET;//真正物理地址()
printk("物理地址是 %x\n",real_addr);
return;
out:
printk("沒有內存映射",real_addr);
8. linux在具有快表的段頁式存儲管理公式中,如何實現地址變換
在段頁式系統中,為了便於實現地址變換,須配置一個段表寄存器,其中存放段表始址和段長TL。
進行地址變換時,首先利用段號S,將它與段長TL進行比較。若S<TL,表示未越界,利用段表始址和段號來求出該段所對應的段表項在段表中的位置,從中得到該段的頁表始址,並利用邏輯地址中的段內頁號P來獲得對應頁的頁表項位置,從中讀出該頁所在的物理塊號b,再利用塊號b和頁內地址來構成物理地址。 在段頁式系統中,為了獲得一條指令或數據,須三次訪問內存。第一次訪問內存中的段表,從中取得頁表始址;第二次訪問內存中的頁表,從中取出該頁所在的物理塊號,並將該塊號與頁內地址一起形成指令或數據的物理地址;第三次訪問才是真正從第二次訪問所得的地址中,取出指令或數據。 顯然,這使訪問內存的次數增加了近兩倍。 為了提高執行速度,在地址變換機構中增設一個高速緩沖寄存器。每次訪問它時,都須同時利用段號和頁號去檢索高速緩存,若找到匹配的表項,便可從中得到相應頁的物理塊號,用來與頁內地址一起形成物理地址;若未找到匹配表項,則仍須再三次訪問內存。
復制的。
9. linux:誰能給我解釋下虛擬地址和物理地址的聯系
這個問題很大。。。。我盡自己所能給你解釋一下吧,如果你不能完全看懂,以後可以回頭再翻翻來看。關於虛擬內存的事情,大概是這樣的:
首先你要明確什麼是虛擬內存。虛擬內存實際上是操作系統對於內存管理的一種方式,比如說,對每個程序而言,它的內存編址都從0x00到0xff,但是實際上,這些內存對應的物理地址,應用程序本身是無法知道的,在這里就可以理解成操作系統對內存管理的一層抽象。
比如,可能進程init的虛擬地址0x00對應了物理地址的0x10,而kthreadd的虛擬地址0x00對應物理地址0x20,etc.
而且虛擬內存也是一種有效的進程間隔離的方式,極大的提升了進程的安全性和操作系統的穩定性,也就是我一個進程不管做什麼,都是在它自己的地址空間里做的,不會影響到其他進程和OS。
當然這是理想情況,實際上還有進程間通信啦之類,這就不在這個問題的范圍之內了。
而具體怎麼把這些虛擬地址對應到物理地址上,這是操作系統做的事情,估計這個也就是你的問題。
----以上是背景1-----
然後我要明確一下:地址匯流排4位的意思是說內存用4個bit位來表達地址,所以能夠index的地址位就是2^0-2^4,也就是0x0到0xf,就是16個bit的內存空間。
然後我們再來細化一下你的例子,就比方說在你的16bit的內存的機器上有1個OS,上面跑著2個程序。一般來說OS會保留地址的高位,比如11-15bit的位置,作為kernel space;然後0-10bit是user space。
在以上的前提下,虛擬內存的效果是:在每一個程序看來,這個程序都有0x0到0xf的地址可以用,並且它們的0xb-0xf都是shared kernel space,然後0x0-0xa都是自己的user space,這樣彷彿就有了32個bit的地址一樣。這就是你所謂的是用虛擬地址可以使總的地址操作物理地址。至於os是怎麼做到這點的,繼續往下看。
-----以上是背景2-----
操作系統對每一個進程有一個進程式控制制塊,叫PCB,Process Control Block,里邊存儲了每一個進程的進程信息,比如說寄存器,file descriptor,還有我們最關心的內存映射信息。每一個進程有一個遞增的id號,叫pid,也就是Process IDentifier.
-----以上是背景3-----
進程間切換,也就是說,比如說你一個系統只有1個CPU,但是有兩個進程要跑,而且要讓我們看起來好像是兩個進程同時在跑一樣。為什麼我要提到這個呢,後面繼續看。
-----以上是背景4-----
好,現在來講如何把虛擬地址映射到物理地址。從程序的角度來看,從malloc開始講起,比如,在某一時刻,一個進程調用了malloc,在堆(heap)上申請了2bits的空間。實際上這個行為的流程是,程序調用malloc,進入內核模式之後,調用mmap,如果成功,操作系統會從物理地址上取一塊2bits的內存,交給應用程序編入虛擬地址空間。更詳細一點說,每個進程對內存管理是一個紅黑樹的結構,也就是說,在每一個進程的PCB,里維護了一顆紅黑樹,然後動態的將所有的新分配的內存加到這個紅黑樹里邊,以保證程序對每一塊內存的訪問時間是差不多的。然後不知道你們教材中有沒有提到頁表(page table),頁表也是PCB中的一項,你們教材中應該會對頁表有詳細的講解,將如何對內存的地址進行換算,之類的。然後你要明確,頁表實際上是紅黑樹的cache,這樣可以加速程序對於常用的內存的訪問速度。
以上是操作系統對內存管理的一個大致概括,就是一塊物理的內存如何映射成為一塊虛擬的內存。
我在背景2中說,兩個程序都看到自己有16個bit的虛擬地址,總共有32bit,但是實際上硬體只有16bits,也就是說,不管你在紅黑樹和頁表中怎麼映射,一定會有沖突發生,比如,可能物理地址的0x02對應了進程1中的0x04,又在進程2的PCB中映射到了pid2的虛擬地址位0x06上。操作系統如何解決這個矛盾呢,首先在進程pid 1運行的時候,這個0x02對應的是pid1中的0x04;然後這個時候進程切換發生了,pid 2開始運行。當pid2需要用到它的0x04時,os發現0x02這個地址在pid1中也有映射,於是它就把0x02這個地址上的內容存到硬碟上的一個叫swap的空間內,然後把這個地址交給pid2使用。這樣就達到了擴大虛擬地址的效果。
但是這樣做是有代價的,因為一旦這個page被swap出去,那麼在pid1再來調用的時候會發生一系列的miss,從L1 cache miss到 L2 cache miss到L3 cache miss,然後頁表miss,memory miss,會對程序的性能造成極大的影響。影響有多大呢,平均來說:
L1 cache hit: 0.5ns
L2 cache hit: 7ns
主內存引用:100ns
順序從內存中讀取1MB:250,000ns
硬碟尋道:10,000,000ns
從硬碟上順序讀取1MB:30,000,000ns
所以你就可以知道這種行為是以極大的性能為代價的。
----講完啦-----
總的來說這個很大的話題,我剛才所寫的東西的就是試圖讓你對虛擬內存這個東西有一個基本的概念,然後大致的了解內存是如何映射的。就我現在能想到的,對這個虛擬內存話題的討論還包括多級頁表,進程間隔離&通信以及memory fragment。
個人水平有限,如果以上有什麼地方說錯的或者遺漏的,還請各位多多補充和批評,謝謝。
10. 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系統開發有所幫助.