Linux虛擬位址與物理地址的映射關係分析

來源:互聯網
上載者:User

Linux虛擬位址與物理地址的映射關係分析

 

1. 虛擬空間

 

0-3G 使用者空間 0x00000000 ~ 0xbfffffff

3-4G 核心空間 0xc0000000 ~ 0xffffffff

每個使用者進程都有獨立的使用者空間(虛擬位址0-3),而核心空間是唯一的(相當於共用)

每個進程的使用者空間用mm_struct描述,即task_struct.mm。

2.進程虛擬位址的組織2.1 虛擬空間、使用者空間

 

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 */...//描述使用者空間的段分布:資料區段,程式碼片段,堆棧段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;...};
以上結構描述了進程的使用者空間的結構,其中
pgd_t 是該進程使用者空間地址映射到物理地址時使用
vm_area_struct 是進程使用者空間已映射到物理空間的虛擬位址區間,mmap是該空間區塊組成的鏈表。

虛擬空間的空洞:虛擬空間還未被映射的區塊(即沒有被使用),那麼就沒有vm_area_struct結構

2.2 記憶體區間

 

 

/* * 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;//該區間的許可權及標誌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;//用於將磁碟檔案對應至使用者空間...};

虛擬空間區間的描述中:
vm_start/vm_end 為該區塊的起始和結束位址
vm_file 是在檔案對應中使用到,即常用的mmap(fd,...)函數,簡單說即將虛擬空間映射至檔案在核心的緩衝區,那麼這時候訪問該虛擬空間將有別於pgd的映射。
vm_operations_struct 為本虛擬區間的操作,其中的nopage函數指標是處理記憶體缺頁而使用的。對於通用的記憶體映射,該缺頁處理函數為do_no_page()將虛擬位址映射到物理地址(匿名映射):分配物理頁& 設定pgd & pte。
而對於mmap操作相關的虛擬位址,其缺頁處理函數將和檔案系統的缺頁函數相關,filemap_nopage(),通過檔案系統的缺頁從磁碟將相關檔案塊載入如核心緩衝區.

 

 

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.系統物理地址的組織

核心將物理地址按頁來組織,struct page描述系統的物理頁的資訊,但是頁的資料內容是不在該結構中的。系統有全域資料 struct page mem_map[],用於記錄每個物理頁。
頁面大小為4kb,在源碼中用體現為(PAGE_SHIFT = 12)

 

/* * 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是用於描述一個物理頁面,該結構僅僅是作為描述,也就是說該頁面的4kb資料時儲存於某個連續的4kb的物理空間(由MMU決定,具體見下文)。其中:
lru 頁面緩衝的調度策略(最少使用優先)

題外話:
page也可以用於檔案緩衝,相關參數及作用:
buffer_head 是和裝置檔案相關的操作,例如在檔案系統中,file的一個page有4個塊,這些塊就儲存於buffer_head鏈表指定的記憶體中。
index 在檔案系統中是用於file緩衝的頁號。

 

3.1 使用者空間頁面目錄(映射關係)

 

進程的虛擬空間描述中,pgd是用於頁式儲存的映射使用。當核心發生進程切換時,將新進程的pgd載入CR3寄存器,CPU中的MMU單元依據CR3寄存器進行頁面映射。

pgd,pmd和pte可以看做是數組,為進程的地址空間到物理空間實現映射。其中虛擬位址的高位地址決定pgd,中間段地址決定pmd,而低位地址決定pte,pte是“page table entry”。
最終定位的pte中存放的即為對應物理頁面的指標。
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;//操作標誌


3.2使用者空間的映射:

1. 使用者空間的虛擬位址vaddr通過MMU(pgd,pmd,pte)找到對應的頁表項x(即為物理地址)
2. 頁表項x的高20位是物理也好,物理頁號index = x >> PAGE_SHIFT, 同理,index後面補上12個0就是物理頁表的首地址。
3. 通過物理頁號,我們可以再核心中找到該物理頁的描述的指標mem_map[index],當然這個指標是虛擬位址,page結構見上文。

 

3.3核心空間虛擬位址的映射:

核心空間與物理地址之間有直接的映射關係,而不需要向使用者空間那樣通過mmu(pgd)。系統空間映射(3G開始)到物理空間0G起始:
例如:
系統核心映像載入的虛擬位址為3G+1M的起始地址,那麼對應的物理地址為1M。
緊接著分配在3G+2M開始分配了8M的虛擬位址(物理地址為2-9M)用於PDG
之後預留了16M空間用DMA於儲存。
而全域的page結構的mem_page[]數組是在0xc1000000開始的。
所以核心空間虛擬位址到物理地址的轉換為:

 

PAGE_OFFSET = 3GBvitr_to_phys(kadd)  return vadd - PAGE_OFFSET  核心空間的虛擬位址vaddr是通過如下方式找到它對應物理地址的page結構:vitr_to_page(vadd)index = virt_to_phys(kadd) >> PAGE_SHIFTreturn mem_map[index]


 



 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.